This PR configure `#entry-point` import alias for javascript bindings in
order to use `browser.js` napi-rs generated file in browser context.
Also, this PR forces napi-rs to emit `index.js` entrypoint using ESM and
also use typescript for writing our wrapper code around napi-rs
bindings.
In order to make behaviour consistent when lib is imported through ESM
or CommonJS this PR also replace default export of `Database` by named
on. The problem is that `export default Database` will be logically
equivalent to `modules.export.default = Database` which is not the same
thing as `modules.export = Database` and this will need to access
additional `.default` field with CommonJs style imports (e.g. `new
require('@tursodatabase/turso').default(...)`). In order to remove this
difference - I just replaced default export with named one.
Closes#2488
Fixes the following error:
```
This is not the tsc command you are looking for
To get access to the TypeScript compiler, tsc, from the command line either:
- Use npm install typescript to first add TypeScript to your project before using npx
- Use yarn to avoid accidentally running code from un-installed packages
```
This PR adds support for the PRAGMA `query_only` pragma, which enables
or disables write operations on a database connection. It allows
applications to mark the connection as read-only at runtime.
Reviewed-by: Preston Thorpe <preston@turso.tech>
Closes#2498
1. We spend a lot of time in `cell_get_raw_region` in the balancing
routine, and especially calling `contents.page_type()` there a lot, so
extract a version that can take some precomputed arguments so those
don't have to be redundantly computed multiple times for successive
calls where those values are going to be the same
2. Avoid calling `self.usable_space()` in a loop in
`insert_into_page()`.
3. Avoid accessing `pages_in_frames` lock if we're not going to modify
it
main improvement is to the "insert 100 rows" bench which ends up doing
balancing a lot:
```
Insert rows in batches/limbo_insert_1_rows
time: [22.856 µs 24.342 µs 27.496 µs]
change: [-3.3579% +15.495% +67.671%] (p = 0.62 > 0.05)
No change in performance detected.
Benchmarking Insert rows in batches/limbo_insert_10_rows: Collecting 100 samples in estim
Insert rows in batches/limbo_insert_10_rows
time: [32.196 µs 32.604 µs 32.981 µs]
change: [+1.3253% +2.9177% +4.5863%] (p = 0.00 < 0.05)
Performance has regressed.
Insert rows in batches/limbo_insert_100_rows
time: [89.425 µs 92.105 µs 96.304 µs]
change: [-18.317% -13.605% -9.1022%] (p = 0.00 < 0.05)
Performance has improved.
```
Reviewed-by: Preston Thorpe <preston@turso.tech>
Closes#2483
Trying to support this is unnecessary and just adds branches and bit ops
when we could just round the allocation up or down
Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>
Closes#2497
# Note: this pull request is built on top of #2491 so let's merge that
one first.
## Problem:
A very easy source of bugs is to mistakenly use e.g.
`PageContent::read_u16()` instead of
`PageContent::read_u16_no_offset()`. The difference between the two is
that `read_u16()` adds 100 bytes to the requested byte offset if and
only if the page in question is page 1, which contains a 100-byte
database header.
Case in point about this being easy to misuse: see #2491.
## Observation:
In all of the cases where we want to read from or write to a page
"header-sensitively" (taking the possible db header into account), those
reads/writes are to statically known offsets, e.g. specific known bytes
in a btree page header.
In all other cases, the "no-offset" versions, i.e. the ones taking the
absolute byte offset as parameter, should be used - the common use cases
for these are reading/writing to some absolute offset that you just read
from another location on a page, for example. Another use case is
writing to specific offsets on overflow pages and freelist pages, which
we can in the future expose more methods for, but right now they can
always use the "no offset" versions safely, because neither of those
page types can ever be page 1.
## Solution:
1. Make all the offset-sensitive versions (`read_u16()` and friends)
private methods of `PageContent`.
2. Expose dedicated public methods for things like updating rightmost
pointer, updating fragmented bytes count and so on, and use them instead
of the plain read/write methods universally.
## Follow-up:
I will perhaps follow this up with a renaming PR that renames
`read_xxx_no_offset()` to just `read_xxx()` and gives the private
header-sensitive methods new names.
Reviewed-by: Preston Thorpe <preston@turso.tech>
Closes#2493
Problem:
A very easy source of bugs is to mistakenly use e.g. PageContent::read_u16()
instead of PageContent::read_u16_no_offset(). The difference between the two
is that `read_u16()` adds 100 bytes to the requested byte offset if and only if
the page in question is page 1, which contains a 100-byte database header.
Case in point: see #2491.
Observation:
In all of the cases where we want to read from or write to a page "header-sensitively",
those reads/writes are to so-called "well known offsets", e.g. specific bytes in a btree
page header.
In all other cases, the "no-offset" versions, i.e. the ones taking the absolute byte offset
as parameter, should be used.
Solution:
1. Make all the offset-sensitive versions (read_u16() and friends) private methods of
`PageContent`.
2. Expose dedicated methods for things like updating rightmost pointer, updating fragmented
bytes count and so on, and use them instead of the plain read/write methods universally.