@fuzdev/fuz_app 0.132.1 → 0.134.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/db/CLAUDE.md +11 -8
- package/dist/db/create_db.d.ts +8 -6
- package/dist/db/create_db.d.ts.map +1 -1
- package/dist/db/create_db.js +11 -10
- package/dist/db/db.d.ts +9 -7
- package/dist/db/db.d.ts.map +1 -1
- package/dist/db/db.js +5 -4
- package/dist/db/db_pglet.d.ts +43 -0
- package/dist/db/db_pglet.d.ts.map +1 -0
- package/dist/db/db_pglet.js +55 -0
- package/dist/db/fact_disk_storage.d.ts +3 -3
- package/dist/db/fact_disk_storage.d.ts.map +1 -1
- package/dist/db/fact_disk_storage.js +11 -11
- package/dist/db/fact_store.d.ts +4 -4
- package/dist/db/fact_store.js +3 -3
- package/dist/db/fact_store_errors.d.ts +3 -3
- package/dist/db/fact_store_errors.d.ts.map +1 -1
- package/dist/db/fact_store_errors.js +5 -5
- package/dist/testing/CLAUDE.md +17 -18
- package/dist/testing/app_server.d.ts +5 -5
- package/dist/testing/app_server.d.ts.map +1 -1
- package/dist/testing/app_server.js +21 -20
- package/dist/testing/cross_backend/default_backend_configs.d.ts +5 -5
- package/dist/testing/cross_backend/default_backend_configs.d.ts.map +1 -1
- package/dist/testing/cross_backend/default_backend_configs.js +1 -1
- package/dist/testing/cross_backend/in_process_setup.d.ts +2 -2
- package/dist/testing/cross_backend/in_process_setup.js +3 -3
- package/dist/testing/cross_backend/test_cell_gated_create_authorize.js +1 -1
- package/dist/testing/cross_backend/testing_reset_actions.d.ts +2 -2
- package/dist/testing/cross_backend/testing_reset_actions.js +1 -1
- package/dist/testing/cross_backend/ts_spine_backend_config.d.ts +2 -2
- package/dist/testing/cross_backend/ts_spine_backend_config.d.ts.map +1 -1
- package/dist/testing/db.d.ts +49 -60
- package/dist/testing/db.d.ts.map +1 -1
- package/dist/testing/db.js +104 -101
- package/dist/testing/rate_limiting.d.ts +2 -1
- package/dist/testing/rate_limiting.d.ts.map +1 -1
- package/dist/testing/rate_limiting.js +2 -2
- package/dist/testing/sse_round_trip.d.ts +1 -1
- package/dist/testing/sse_round_trip.d.ts.map +1 -1
- package/dist/testing/sse_round_trip.js +2 -2
- package/dist/testing/stubs.js +1 -1
- package/package.json +8 -3
package/dist/db/CLAUDE.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# db/
|
|
2
2
|
|
|
3
|
-
> Database layer: the `Db` abstraction over pg
|
|
3
|
+
> Database layer: the `Db` abstraction over pg, PGlite and pglet, the migration
|
|
4
4
|
> runner, and the cell content-primitive schema + queries.
|
|
5
5
|
|
|
6
6
|
For server assembly, `QueryDeps`, and migration-runner contract see the
|
|
@@ -12,20 +12,23 @@ the code.
|
|
|
12
12
|
|
|
13
13
|
## Generic db infrastructure
|
|
14
14
|
|
|
15
|
-
- `db.ts` — `Db` abstraction over pg
|
|
15
|
+
- `db.ts` — `Db` abstraction over pg, PGlite and pglet, `query` / `query_one` /
|
|
16
16
|
`transaction`, `no_nested_transaction` guard.
|
|
17
17
|
- `create_db.ts` — URL-based driver auto-detection (`postgres` /
|
|
18
|
-
`pglite-file` / `
|
|
19
|
-
-
|
|
20
|
-
|
|
18
|
+
`pglite-file` for `file://` / `pglet-memory` for `memory://`, over
|
|
19
|
+
`@fuzdev/pglet-wasm`). An in-memory PGlite is `create_pglite_db(new PGlite())`.
|
|
20
|
+
- `db_pg.ts` / `db_pglite.ts` / `db_pglet.ts` — driver adapters. `db_pg.ts` also
|
|
21
|
+
exports `register_pg_type_parsers`, the shared int8→number coercion (so
|
|
21
22
|
`BIGSERIAL` columns read as JS numbers, matching PGlite) — called by both
|
|
22
23
|
`create_db` and the test pg factory (`testing/db.ts`) so prod and tests
|
|
23
|
-
read the same wire shape from one registration site.
|
|
24
|
+
read the same wire shape from one registration site. `db_pglet.ts`'s
|
|
25
|
+
`PGLET_COERCION` is pglet's half of the same convention, which every pglet
|
|
26
|
+
instance fuz_app creates is given.
|
|
24
27
|
- `migrate.ts` — advisory-lock migration runner (`run_migrations`,
|
|
25
28
|
`baseline`), `Migration` / `MigrationNamespace` / `MigrationError`.
|
|
26
29
|
- `query_deps.ts` — `QueryDeps = {db}`, the first param to every `query_*`.
|
|
27
30
|
- `assert_row.ts` — `assert_row(row, context)` for INSERT … RETURNING.
|
|
28
|
-
- `pg_error.ts` — `pg_error_code` (SQLSTATE extractor for `pg`/PGlite errors), `is_pg_unique_violation` (Postgres `23505`).
|
|
31
|
+
- `pg_error.ts` — `pg_error_code` (SQLSTATE extractor for `pg`/PGlite/pglet errors), `is_pg_unique_violation` (Postgres `23505`).
|
|
29
32
|
- `sql_identifier.ts` — `assert_valid_sql_identifier`.
|
|
30
33
|
- `sql_columns.ts` — `columns_sql` / `qualify_columns` / `omit_columns`,
|
|
31
34
|
the derivation helpers every `*_COLUMNS` projection const's variants
|
|
@@ -178,7 +181,7 @@ DO NOTHING`), `_put_fact_refs`, `_get_fact` / `_get_fact_meta` / `_has_fact`
|
|
|
178
181
|
`fsync`ed before the rename publishes it (twins the Rust `fuz_fact` §fsync
|
|
179
182
|
posture: data-sync before rename, parent-dir fsync waived) — the serve path
|
|
180
183
|
streams the file without re-hashing, so write-time durability is the guard.
|
|
181
|
-
- **`fact_store_errors.ts`** — `
|
|
184
|
+
- **`fact_store_errors.ts`** — `FactPayloadTooLargeError` / `FactStorageFullError` (+
|
|
182
185
|
`is_enospc_error`) thrown by `put_stream`, for a consumer route's 413 / 507.
|
|
183
186
|
- The HTTP serving plumbing lives under `server/` (`serve_fact_route.ts`,
|
|
184
187
|
`x_accel.ts`).
|
package/dist/db/create_db.d.ts
CHANGED
|
@@ -4,11 +4,12 @@
|
|
|
4
4
|
* Selects the appropriate database driver based on `database_url`:
|
|
5
5
|
* - `postgres://` or `postgresql://` — uses `pg` (PostgreSQL)
|
|
6
6
|
* - `file://` — uses `@electric-sql/pglite` (file-based)
|
|
7
|
-
* - `memory://` — uses `@
|
|
7
|
+
* - `memory://` — uses `@fuzdev/pglet-wasm` (in-memory)
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
* dynamically imported only when needed. For direct driver
|
|
11
|
-
* without auto-detection, use `db/db_pg.ts
|
|
9
|
+
* `pg`, `@electric-sql/pglite` and `@fuzdev/pglet-wasm` are optional peer
|
|
10
|
+
* dependencies, dynamically imported only when needed. For direct driver
|
|
11
|
+
* construction without auto-detection, use `db/db_pg.ts`, `db/db_pglite.ts`
|
|
12
|
+
* or `db/db_pglet.ts` — an in-memory PGlite is `create_pglite_db(new PGlite())`.
|
|
12
13
|
*
|
|
13
14
|
* @module
|
|
14
15
|
*/
|
|
@@ -28,12 +29,13 @@ export interface CreateDbResult {
|
|
|
28
29
|
* know which driver is in use.
|
|
29
30
|
*
|
|
30
31
|
* For direct driver construction without URL routing, import
|
|
31
|
-
* `create_pg_db` from `db/db_pg.ts
|
|
32
|
+
* `create_pg_db` from `db/db_pg.ts`, `create_pglite_db` from `db/db_pglite.ts`
|
|
33
|
+
* or `create_pglet_db_driver` from `db/db_pglet.ts`.
|
|
32
34
|
*
|
|
33
35
|
* @param database_url - connection URL (`postgres://`, `postgresql://`, `file://`, or `memory://`)
|
|
34
36
|
* @returns database instance, close callback, type, and display name
|
|
35
37
|
* @throws Error if `database_url` uses an unsupported scheme. Driver
|
|
36
|
-
* construction (`pg.Pool` or
|
|
38
|
+
* construction (`pg.Pool`, `PGlite` or pglet) may also throw on bad connection
|
|
37
39
|
* parameters or missing peer-dependency packages.
|
|
38
40
|
*/
|
|
39
41
|
export declare const create_db: (database_url: string) => Promise<CreateDbResult>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create_db.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/create_db.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"create_db.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/create_db.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAK1C,yCAAyC;AACzC,MAAM,WAAW,cAAc;IAC9B,EAAE,EAAE,EAAE,CAAC;IACP,iFAAiF;IACjF,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,SAAS,GAAU,cAAc,MAAM,KAAG,OAAO,CAAC,cAAc,CAiC5E,CAAC"}
|
package/dist/db/create_db.js
CHANGED
|
@@ -4,16 +4,18 @@
|
|
|
4
4
|
* Selects the appropriate database driver based on `database_url`:
|
|
5
5
|
* - `postgres://` or `postgresql://` — uses `pg` (PostgreSQL)
|
|
6
6
|
* - `file://` — uses `@electric-sql/pglite` (file-based)
|
|
7
|
-
* - `memory://` — uses `@
|
|
7
|
+
* - `memory://` — uses `@fuzdev/pglet-wasm` (in-memory)
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
* dynamically imported only when needed. For direct driver
|
|
11
|
-
* without auto-detection, use `db/db_pg.ts
|
|
9
|
+
* `pg`, `@electric-sql/pglite` and `@fuzdev/pglet-wasm` are optional peer
|
|
10
|
+
* dependencies, dynamically imported only when needed. For direct driver
|
|
11
|
+
* construction without auto-detection, use `db/db_pg.ts`, `db/db_pglite.ts`
|
|
12
|
+
* or `db/db_pglet.ts` — an in-memory PGlite is `create_pglite_db(new PGlite())`.
|
|
12
13
|
*
|
|
13
14
|
* @module
|
|
14
15
|
*/
|
|
15
16
|
import { create_pg_db, register_pg_type_parsers } from './db_pg.js';
|
|
16
17
|
import { create_pglite_db } from './db_pglite.js';
|
|
18
|
+
import { create_pglet_db_driver, create_pglet_instance } from './db_pglet.js';
|
|
17
19
|
/**
|
|
18
20
|
* Create a database connection based on a URL.
|
|
19
21
|
*
|
|
@@ -21,12 +23,13 @@ import { create_pglite_db } from './db_pglite.js';
|
|
|
21
23
|
* know which driver is in use.
|
|
22
24
|
*
|
|
23
25
|
* For direct driver construction without URL routing, import
|
|
24
|
-
* `create_pg_db` from `db/db_pg.ts
|
|
26
|
+
* `create_pg_db` from `db/db_pg.ts`, `create_pglite_db` from `db/db_pglite.ts`
|
|
27
|
+
* or `create_pglet_db_driver` from `db/db_pglet.ts`.
|
|
25
28
|
*
|
|
26
29
|
* @param database_url - connection URL (`postgres://`, `postgresql://`, `file://`, or `memory://`)
|
|
27
30
|
* @returns database instance, close callback, type, and display name
|
|
28
31
|
* @throws Error if `database_url` uses an unsupported scheme. Driver
|
|
29
|
-
* construction (`pg.Pool` or
|
|
32
|
+
* construction (`pg.Pool`, `PGlite` or pglet) may also throw on bad connection
|
|
30
33
|
* parameters or missing peer-dependency packages.
|
|
31
34
|
*/
|
|
32
35
|
export const create_db = async (database_url) => {
|
|
@@ -43,10 +46,8 @@ export const create_db = async (database_url) => {
|
|
|
43
46
|
};
|
|
44
47
|
}
|
|
45
48
|
if (database_url.startsWith('memory://')) {
|
|
46
|
-
const {
|
|
47
|
-
|
|
48
|
-
const { db, close } = create_pglite_db(pglite);
|
|
49
|
-
return { db, close, db_type: 'pglite-memory', db_name: '(memory)' };
|
|
49
|
+
const { db, close } = create_pglet_db_driver(await create_pglet_instance());
|
|
50
|
+
return { db, close, db_type: 'pglet-memory', db_name: '(memory)' };
|
|
50
51
|
}
|
|
51
52
|
if (database_url.startsWith('file://')) {
|
|
52
53
|
const path = new URL(database_url).pathname;
|
package/dist/db/db.d.ts
CHANGED
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
* Database wrapper with duck-typed interface.
|
|
3
3
|
*
|
|
4
4
|
* Accepts any client with a query(text, values) method.
|
|
5
|
-
*
|
|
5
|
+
* `pg.Pool`, `@electric-sql/pglite` and `@fuzdev/pglet-wasm` all satisfy this interface.
|
|
6
6
|
*
|
|
7
7
|
* Transaction safety is provided by an injected `transaction` callback —
|
|
8
|
-
* the driver adapters (`db/db_pg.ts`, `db/db_pglite.ts`) supply the driver-appropriate
|
|
8
|
+
* the driver adapters (`db/db_pg.ts`, `db/db_pglite.ts`, `db/db_pglet.ts`) supply the driver-appropriate
|
|
9
9
|
* implementation. Close is handled externally (returned alongside the `Db`
|
|
10
10
|
* as `DbDriverResult`), not as a method on this class.
|
|
11
11
|
*
|
|
12
12
|
* @module
|
|
13
13
|
*/
|
|
14
14
|
/**
|
|
15
|
-
* Minimal interface that
|
|
15
|
+
* Minimal interface that pg, pglite and pglet satisfy.
|
|
16
16
|
*/
|
|
17
17
|
export interface DbClient {
|
|
18
18
|
query: <T = unknown>(text: string, values?: Array<unknown>) => Promise<{
|
|
@@ -25,6 +25,7 @@ export interface DbClient {
|
|
|
25
25
|
* `transaction` is injected by `create_db` which knows the driver.
|
|
26
26
|
* For `pg`: acquires a dedicated pool client per transaction.
|
|
27
27
|
* For PGlite: delegates to `pglite.transaction()`.
|
|
28
|
+
* For pglet: delegates to the adapter's `transaction()`.
|
|
28
29
|
*/
|
|
29
30
|
export interface DbDeps {
|
|
30
31
|
client: DbClient;
|
|
@@ -33,7 +34,7 @@ export interface DbDeps {
|
|
|
33
34
|
/**
|
|
34
35
|
* Result of constructing a driver-specific `Db`.
|
|
35
36
|
*
|
|
36
|
-
* Returned by `create_pg_db()` and `
|
|
37
|
+
* Returned by `create_pg_db()`, `create_pglite_db()` and `create_pglet_db_driver()`.
|
|
37
38
|
* The `close` callback is bound to the actual driver — callers
|
|
38
39
|
* never need to know which driver is in use.
|
|
39
40
|
*/
|
|
@@ -43,7 +44,7 @@ export interface DbDriverResult {
|
|
|
43
44
|
close: () => Promise<void>;
|
|
44
45
|
}
|
|
45
46
|
/** Database driver type. */
|
|
46
|
-
export type DbType = 'postgres' | 'pglite-file' | '
|
|
47
|
+
export type DbType = 'postgres' | 'pglite-file' | 'pglet-memory';
|
|
47
48
|
/**
|
|
48
49
|
* Sentinel transaction function for transaction-scoped `Db` instances.
|
|
49
50
|
*
|
|
@@ -56,8 +57,9 @@ export declare const no_nested_transaction: DbDeps['transaction'];
|
|
|
56
57
|
/**
|
|
57
58
|
* Database wrapper providing a consistent query and transaction interface.
|
|
58
59
|
*
|
|
59
|
-
* Construct via `create_pg_db()` from `db/db_pg.ts
|
|
60
|
-
* `db/db_pglite.ts`
|
|
60
|
+
* Construct via `create_pg_db()` from `db/db_pg.ts`, `create_pglite_db()` from
|
|
61
|
+
* `db/db_pglite.ts` or `create_pglet_db_driver()` from `db/db_pglet.ts` for proper
|
|
62
|
+
* transaction support, or via `create_db()` for
|
|
61
63
|
* URL-based auto-detection.
|
|
62
64
|
*
|
|
63
65
|
* @example
|
package/dist/db/db.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"db.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/db.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;;GAEG;AACH,MAAM,WAAW,QAAQ;IACxB,KAAK,EAAE,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAA;KAAE,CAAC,CAAC;CAC3F;AAED
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/db.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH;;GAEG;AACH,MAAM,WAAW,QAAQ;IACxB,KAAK,EAAE,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC;QAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAA;KAAE,CAAC,CAAC;CAC3F;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,MAAM;IACtB,MAAM,EAAE,QAAQ,CAAC;IACjB,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;CAC9D;AAED;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC9B,EAAE,EAAE,EAAE,CAAC;IACP,iFAAiF;IACjF,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED,4BAA4B;AAC5B,MAAM,MAAM,MAAM,GAAG,UAAU,GAAG,aAAa,GAAG,cAAc,CAAC;AAEjE;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,EAAE,MAAM,CAAC,aAAa,CAEvD,CAAC;AAEF;;;;;;;;;;;;;;;;;;GAkBG;AACH,qBAAa,EAAE;;IACd,QAAQ,CAAC,MAAM,EAAE,QAAQ,CAAC;gBAId,OAAO,EAAE,MAAM;IAK3B;;;;;;OAMG;IACG,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAKxE;;;;;;OAMG;IACG,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IAKjF;;;;;;;;;;;OAWG;IACG,WAAW,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;CAG/D"}
|
package/dist/db/db.js
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
* Database wrapper with duck-typed interface.
|
|
3
3
|
*
|
|
4
4
|
* Accepts any client with a query(text, values) method.
|
|
5
|
-
*
|
|
5
|
+
* `pg.Pool`, `@electric-sql/pglite` and `@fuzdev/pglet-wasm` all satisfy this interface.
|
|
6
6
|
*
|
|
7
7
|
* Transaction safety is provided by an injected `transaction` callback —
|
|
8
|
-
* the driver adapters (`db/db_pg.ts`, `db/db_pglite.ts`) supply the driver-appropriate
|
|
8
|
+
* the driver adapters (`db/db_pg.ts`, `db/db_pglite.ts`, `db/db_pglet.ts`) supply the driver-appropriate
|
|
9
9
|
* implementation. Close is handled externally (returned alongside the `Db`
|
|
10
10
|
* as `DbDriverResult`), not as a method on this class.
|
|
11
11
|
*
|
|
@@ -25,8 +25,9 @@ export const no_nested_transaction = () => {
|
|
|
25
25
|
/**
|
|
26
26
|
* Database wrapper providing a consistent query and transaction interface.
|
|
27
27
|
*
|
|
28
|
-
* Construct via `create_pg_db()` from `db/db_pg.ts
|
|
29
|
-
* `db/db_pglite.ts`
|
|
28
|
+
* Construct via `create_pg_db()` from `db/db_pg.ts`, `create_pglite_db()` from
|
|
29
|
+
* `db/db_pglite.ts` or `create_pglet_db_driver()` from `db/db_pglet.ts` for proper
|
|
30
|
+
* transaction support, or via `create_db()` for
|
|
30
31
|
* URL-based auto-detection.
|
|
31
32
|
*
|
|
32
33
|
* @example
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pglet driver adapter for `Db`.
|
|
3
|
+
*
|
|
4
|
+
* Provides `create_pglet_instance()`, which loads `@fuzdev/pglet-wasm` on
|
|
5
|
+
* demand and creates an in-memory instance with `PGLET_COERCION`, the value
|
|
6
|
+
* coercion every fuz_app pglet instance is created with, and
|
|
7
|
+
* `create_pglet_db_driver()` to construct a `Db` backed by one. The package is
|
|
8
|
+
* imported dynamically, so it stays an optional peer.
|
|
9
|
+
*
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
import type { CoercionOptions, PgletDb } from '@fuzdev/pglet-wasm';
|
|
13
|
+
import { type DbDriverResult } from './db.js';
|
|
14
|
+
/**
|
|
15
|
+
* The value coercion fuz_app creates every pglet instance with.
|
|
16
|
+
*
|
|
17
|
+
* The adapter defaults int8 to `bigint`; fuz_app reads int8 as a JS number on
|
|
18
|
+
* every driver (`register_pg_type_parsers` for `pg`, PGlite's own default), so
|
|
19
|
+
* `AuditLogEvent.seq` and friends validate identically across drivers.
|
|
20
|
+
*/
|
|
21
|
+
export declare const PGLET_COERCION: CoercionOptions;
|
|
22
|
+
/**
|
|
23
|
+
* Create an in-memory pglet instance with `PGLET_COERCION`.
|
|
24
|
+
*
|
|
25
|
+
* Loads `@fuzdev/pglet-wasm` on demand and awaits its `init()` — a no-op on the
|
|
26
|
+
* package's Node entry, where the wasm loads at import; the browser entry loads
|
|
27
|
+
* it here.
|
|
28
|
+
*
|
|
29
|
+
* @returns a fresh, empty instance; wrap it with `create_pglet_db_driver`
|
|
30
|
+
*/
|
|
31
|
+
export declare const create_pglet_instance: () => Promise<PgletDb>;
|
|
32
|
+
/**
|
|
33
|
+
* Create a `Db` backed by a pglet instance.
|
|
34
|
+
*
|
|
35
|
+
Named `_driver` to stay clear of `@fuzdev/pglet-wasm`'s own `create_pglet_db`,
|
|
36
|
+
* which creates the instance this wraps. Create it with `create_pglet_instance`
|
|
37
|
+
* (or with `PGLET_COERCION`) so it reads values as the other drivers do.
|
|
38
|
+
*
|
|
39
|
+
* @param pglet - a `@fuzdev/pglet-wasm` instance
|
|
40
|
+
* @returns the `Db` instance and a `close` callback bound to `pglet.close()`
|
|
41
|
+
*/
|
|
42
|
+
export declare const create_pglet_db_driver: (pglet: PgletDb) => DbDriverResult;
|
|
43
|
+
//# sourceMappingURL=db_pglet.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db_pglet.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/db_pglet.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAEnE,OAAO,EAA6B,KAAK,cAAc,EAAE,MAAM,SAAS,CAAC;AAEzE;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,EAAE,eAAoC,CAAC;AAElE;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,QAAa,OAAO,CAAC,OAAO,CAI7D,CAAC;AAaF;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB,GAAI,OAAO,OAAO,KAAG,cAGtD,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* pglet driver adapter for `Db`.
|
|
3
|
+
*
|
|
4
|
+
* Provides `create_pglet_instance()`, which loads `@fuzdev/pglet-wasm` on
|
|
5
|
+
* demand and creates an in-memory instance with `PGLET_COERCION`, the value
|
|
6
|
+
* coercion every fuz_app pglet instance is created with, and
|
|
7
|
+
* `create_pglet_db_driver()` to construct a `Db` backed by one. The package is
|
|
8
|
+
* imported dynamically, so it stays an optional peer.
|
|
9
|
+
*
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
import { Db, no_nested_transaction } from './db.js';
|
|
13
|
+
/**
|
|
14
|
+
* The value coercion fuz_app creates every pglet instance with.
|
|
15
|
+
*
|
|
16
|
+
* The adapter defaults int8 to `bigint`; fuz_app reads int8 as a JS number on
|
|
17
|
+
* every driver (`register_pg_type_parsers` for `pg`, PGlite's own default), so
|
|
18
|
+
* `AuditLogEvent.seq` and friends validate identically across drivers.
|
|
19
|
+
*/
|
|
20
|
+
export const PGLET_COERCION = { int8: 'number' };
|
|
21
|
+
/**
|
|
22
|
+
* Create an in-memory pglet instance with `PGLET_COERCION`.
|
|
23
|
+
*
|
|
24
|
+
* Loads `@fuzdev/pglet-wasm` on demand and awaits its `init()` — a no-op on the
|
|
25
|
+
* package's Node entry, where the wasm loads at import; the browser entry loads
|
|
26
|
+
* it here.
|
|
27
|
+
*
|
|
28
|
+
* @returns a fresh, empty instance; wrap it with `create_pglet_db_driver`
|
|
29
|
+
*/
|
|
30
|
+
export const create_pglet_instance = async () => {
|
|
31
|
+
const pglet_wasm = await import('@fuzdev/pglet-wasm');
|
|
32
|
+
await pglet_wasm.init();
|
|
33
|
+
return pglet_wasm.create_pglet_db({ coercion: PGLET_COERCION });
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* Create a transaction implementation for pglet.
|
|
37
|
+
*
|
|
38
|
+
* Delegates to the adapter's single-flight `transaction()` (`BEGIN` / `COMMIT`,
|
|
39
|
+
* `ROLLBACK` on throw).
|
|
40
|
+
*/
|
|
41
|
+
const create_pglet_transaction = (pglet) => async (fn) => pglet.transaction(async (tx) => fn(new Db({ client: tx, transaction: no_nested_transaction })));
|
|
42
|
+
/**
|
|
43
|
+
* Create a `Db` backed by a pglet instance.
|
|
44
|
+
*
|
|
45
|
+
Named `_driver` to stay clear of `@fuzdev/pglet-wasm`'s own `create_pglet_db`,
|
|
46
|
+
* which creates the instance this wraps. Create it with `create_pglet_instance`
|
|
47
|
+
* (or with `PGLET_COERCION`) so it reads values as the other drivers do.
|
|
48
|
+
*
|
|
49
|
+
* @param pglet - a `@fuzdev/pglet-wasm` instance
|
|
50
|
+
* @returns the `Db` instance and a `close` callback bound to `pglet.close()`
|
|
51
|
+
*/
|
|
52
|
+
export const create_pglet_db_driver = (pglet) => ({
|
|
53
|
+
db: new Db({ client: pglet, transaction: create_pglet_transaction(pglet) }),
|
|
54
|
+
close: () => pglet.close()
|
|
55
|
+
});
|
|
@@ -78,12 +78,12 @@ export interface StreamFactToDiskResult {
|
|
|
78
78
|
* `facts_dir`), the buffer + remaining chunks spill to `<facts_dir>/.tmp/…`,
|
|
79
79
|
* then `rename` into `<facts_dir>/<shard>/<rest>` once the hash is known —
|
|
80
80
|
* `{kind: 'disk'}`. A body over the threshold with `facts_dir === undefined`
|
|
81
|
-
* throws `
|
|
82
|
-
* - **Cap enforcement.** Aborts with `
|
|
81
|
+
* throws `FactPayloadTooLargeError` (matches `PgFactStore.put`).
|
|
82
|
+
* - **Cap enforcement.** Aborts with `FactPayloadTooLargeError` the moment the
|
|
83
83
|
* running byte count passes `max_bytes` — the mid-stream backstop for a
|
|
84
84
|
* chunked or mis-declared `Content-Length`.
|
|
85
85
|
* - **Disk-full.** An `ENOSPC` from the temp-file write surfaces as
|
|
86
|
-
* `
|
|
86
|
+
* `FactStorageFullError`.
|
|
87
87
|
*
|
|
88
88
|
* @mutates `facts_dir` filesystem
|
|
89
89
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fact_disk_storage.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/fact_disk_storage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AASH,OAAO,EAAoB,KAAK,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AACnF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE9F,OAAO,EAIN,KAAK,WAAW,EAChB,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"fact_disk_storage.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/fact_disk_storage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AASH,OAAO,EAAoB,KAAK,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AACnF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAE9F,OAAO,EAIN,KAAK,WAAW,EAChB,MAAM,oBAAoB,CAAC;AAO5B,sEAAsE;AACtE,eAAO,MAAM,gBAAgB,SAAS,CAAC;AAEvC,8EAA8E;AAC9E,eAAO,MAAM,0BAA0B,QAAiB,CAAC;AAEzD;;;;GAIG;AACH,MAAM,MAAM,mBAAmB,GAAG,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,WAAW,CAAC,GACnF,IAAI,CAAC,WAAW,EAAE,OAAO,GAAG,QAAQ,GAAG,YAAY,GAAG,OAAO,CAAC,GAC9D,IAAI,CAAC,YAAY,EAAE,mBAAmB,CAAC,GACvC,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;AAE9B;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GAC1B;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,WAAW,CAAA;CAAE,CAAC;AAEvF;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACtC,IAAI,EAAE,QAAQ,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,eAAe,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,mBAAmB,GAC/B,MAAM,IAAI,CACT,mBAAmB,EACnB,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,mBAAmB,GAAG,OAAO,GAAG,MAAM,CACtE,EACD,WAAW,MAAM,GAAG,SAAS,EAC7B,QAAQ,cAAc,CAAC,UAAU,CAAC,EAClC,WAAW,MAAM,EACjB,oBAAoB,MAAM,KACxB,OAAO,CAAC,sBAAsB,CA8GhC,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,wBAAwB,GACpC,MAAM,IAAI,CAAC,mBAAmB,EAAE,OAAO,GAAG,QAAQ,GAAG,QAAQ,GAAG,YAAY,GAAG,OAAO,GAAG,MAAM,CAAC,EAChG,WAAW,MAAM,EACjB,MAAM,QAAQ,EACd,OAAO,UAAU,KACf,OAAO,CAAC,WAAW,CAgBrB,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,yBAAyB,GACrC,MAAM,IAAI,CAAC,mBAAmB,EAAE,WAAW,CAAC,EAC5C,WAAW,MAAM,EACjB,KAAK,MAAM,KACT,OAAO,CAAC,UAAU,CAIpB,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,kBAAkB,GAC9B,MAAM,IAAI,CAAC,mBAAmB,EAAE,SAAS,GAAG,MAAM,GAAG,QAAQ,CAAC,EAC9D,WAAW,MAAM,EACjB,UAAU;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,KAC3D,OAAO,CAAC,MAAM,CA0BhB,CAAC"}
|
|
@@ -36,7 +36,7 @@ import { to_hex } from '@fuzdev/fuz_util/hex.ts';
|
|
|
36
36
|
import { FACT_HASH_PREFIX } from '@fuzdev/fuz_util/hash_schemas.ts';
|
|
37
37
|
import { generate_random_base64url } from '../crypto.js';
|
|
38
38
|
import { fact_disk_path, mint_file_fact_url, parse_file_fact_url } from './file_fact_url.js';
|
|
39
|
-
import { is_enospc_error,
|
|
39
|
+
import { is_enospc_error, FactPayloadTooLargeError, FactStorageFullError } from './fact_store_errors.js';
|
|
40
40
|
/** Subdirectory under `facts_dir` for in-flight atomic temp files. */
|
|
41
41
|
export const FACT_TMP_DIRNAME = '.tmp';
|
|
42
42
|
/** Default age (1 hour) past which a `.tmp/*` file is considered orphaned. */
|
|
@@ -54,12 +54,12 @@ export const FACT_TMP_ORPHAN_MAX_AGE_MS = 60 * 60 * 1000;
|
|
|
54
54
|
* `facts_dir`), the buffer + remaining chunks spill to `<facts_dir>/.tmp/…`,
|
|
55
55
|
* then `rename` into `<facts_dir>/<shard>/<rest>` once the hash is known —
|
|
56
56
|
* `{kind: 'disk'}`. A body over the threshold with `facts_dir === undefined`
|
|
57
|
-
* throws `
|
|
58
|
-
* - **Cap enforcement.** Aborts with `
|
|
57
|
+
* throws `FactPayloadTooLargeError` (matches `PgFactStore.put`).
|
|
58
|
+
* - **Cap enforcement.** Aborts with `FactPayloadTooLargeError` the moment the
|
|
59
59
|
* running byte count passes `max_bytes` — the mid-stream backstop for a
|
|
60
60
|
* chunked or mis-declared `Content-Length`.
|
|
61
61
|
* - **Disk-full.** An `ENOSPC` from the temp-file write surfaces as
|
|
62
|
-
* `
|
|
62
|
+
* `FactStorageFullError`.
|
|
63
63
|
*
|
|
64
64
|
* @mutates `facts_dir` filesystem
|
|
65
65
|
*/
|
|
@@ -76,7 +76,7 @@ export const stream_fact_to_disk = async (deps, facts_dir, source, max_bytes, em
|
|
|
76
76
|
const hash_and_count = (chunk) => {
|
|
77
77
|
size += chunk.length;
|
|
78
78
|
if (size > max_bytes)
|
|
79
|
-
throw new
|
|
79
|
+
throw new FactPayloadTooLargeError(size, max_bytes);
|
|
80
80
|
blake3.update(chunk);
|
|
81
81
|
sha256.update(chunk);
|
|
82
82
|
};
|
|
@@ -111,7 +111,7 @@ export const stream_fact_to_disk = async (deps, facts_dir, source, max_bytes, em
|
|
|
111
111
|
if (facts_dir === undefined) {
|
|
112
112
|
// Over the embedded threshold with nowhere to spill — same shape as the
|
|
113
113
|
// `PgFactStore.put` oversize-without-disk_root reject.
|
|
114
|
-
throw new
|
|
114
|
+
throw new FactPayloadTooLargeError(size, embedded_threshold);
|
|
115
115
|
}
|
|
116
116
|
// Phase 2: spill. A combined stream emits the already-hashed buffered
|
|
117
117
|
// chunks, then continues pulling from `reader`, hashing each remaining
|
|
@@ -154,8 +154,8 @@ export const stream_fact_to_disk = async (deps, facts_dir, source, max_bytes, em
|
|
|
154
154
|
catch (err) {
|
|
155
155
|
await deps.remove(tmp_path).catch(() => undefined);
|
|
156
156
|
if (is_enospc_error(err))
|
|
157
|
-
throw new
|
|
158
|
-
throw err; // includes a mid-stream
|
|
157
|
+
throw new FactStorageFullError(err);
|
|
158
|
+
throw err; // includes a mid-stream FactPayloadTooLargeError surfaced via the stream
|
|
159
159
|
}
|
|
160
160
|
const hash = (FACT_HASH_PREFIX + to_hex(blake3.finalize()));
|
|
161
161
|
const { shard, rest } = await commit_temp_to_cas(deps, tmp_path, facts_dir, hash);
|
|
@@ -197,7 +197,7 @@ export const write_fact_bytes_to_disk = async (deps, facts_dir, hash, bytes) =>
|
|
|
197
197
|
catch (err) {
|
|
198
198
|
await deps.remove(tmp_path).catch(() => undefined);
|
|
199
199
|
if (is_enospc_error(err))
|
|
200
|
-
throw new
|
|
200
|
+
throw new FactStorageFullError(err);
|
|
201
201
|
throw err;
|
|
202
202
|
}
|
|
203
203
|
const { shard, rest } = await commit_temp_to_cas(deps, tmp_path, facts_dir, hash);
|
|
@@ -273,7 +273,7 @@ export const sweep_orphan_temps = async (deps, facts_dir, options) => {
|
|
|
273
273
|
* the file without re-hashing, so the bytes must be stable before they become
|
|
274
274
|
* the canonical body), then either drop the temp (byte-identical content already
|
|
275
275
|
* present — idempotent dedup) or atomically `rename` it into place. On any
|
|
276
|
-
* failure the temp is unlinked and an `ENOSPC` is surfaced as `
|
|
276
|
+
* failure the temp is unlinked and an `ENOSPC` is surfaced as `FactStorageFullError`.
|
|
277
277
|
* The single commit path shared by both writers above — twins the Rust `fuz_fact`
|
|
278
278
|
* `SpillFile::rename_into_cas` (data-sync before rename; parent-dir fsync waived).
|
|
279
279
|
*
|
|
@@ -295,7 +295,7 @@ const commit_temp_to_cas = async (deps, tmp_path, facts_dir, hash) => {
|
|
|
295
295
|
catch (err) {
|
|
296
296
|
await deps.remove(tmp_path).catch(() => undefined);
|
|
297
297
|
if (is_enospc_error(err))
|
|
298
|
-
throw new
|
|
298
|
+
throw new FactStorageFullError(err);
|
|
299
299
|
throw err;
|
|
300
300
|
}
|
|
301
301
|
return { shard, rest };
|
package/dist/db/fact_store.d.ts
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
* oversize `put` throws. `put_stream` needs `fs` for a body of any size — with
|
|
25
25
|
* none it throws before reading the stream — and `disk_root` for the
|
|
26
26
|
* over-threshold spill: with none, a body that passes the threshold throws
|
|
27
|
-
* `
|
|
27
|
+
* `FactPayloadTooLargeError`.
|
|
28
28
|
*
|
|
29
29
|
* Every `external_url` the store writes is a `file:<shard>/<rest>` URL into its
|
|
30
30
|
* own disk CAS, and that CAS is the only place `get` reads external bytes from
|
|
@@ -58,7 +58,7 @@ export declare const FACT_EMBEDDED_THRESHOLD_DEFAULT: number;
|
|
|
58
58
|
* reads disk-backed facts from it. When either is unset the store writes
|
|
59
59
|
* embedded rows only and `get` returns `null` for an external row: an oversize
|
|
60
60
|
* `put` throws; `put_stream` throws for a body of any size when `fs` is unset,
|
|
61
|
-
* and with `fs` but no `disk_root` throws `
|
|
61
|
+
* and with `fs` but no `disk_root` throws `FactPayloadTooLargeError` for a body
|
|
62
62
|
* that passes the threshold. `log` is optional — its call sites are the
|
|
63
63
|
* warnings on the paths where `get` returns `null` for an external row.
|
|
64
64
|
*/
|
|
@@ -91,8 +91,8 @@ export declare class PgFactStore implements FactStore {
|
|
|
91
91
|
* BLAKE3 + SHA-256 in one pass, buffer to the embedded threshold, spill to the
|
|
92
92
|
* disk CAS), then inserts the `fact` row by placement — embedded bytes go to
|
|
93
93
|
* the PG `bytes` column, disk-spilled bytes record the `file:` `external_url`.
|
|
94
|
-
* The cap is enforced mid-stream (`
|
|
95
|
-
* stream throws `
|
|
94
|
+
* The cap is enforced mid-stream (`FactPayloadTooLargeError`); a disk-full mid-
|
|
95
|
+
* stream throws `FactStorageFullError`.
|
|
96
96
|
*
|
|
97
97
|
* Refs: explicit `options.refs` are recorded; JSON auto-extraction is NOT
|
|
98
98
|
* attempted (it would need a buffered re-read, defeating the bounded-memory
|
package/dist/db/fact_store.js
CHANGED
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
* oversize `put` throws. `put_stream` needs `fs` for a body of any size — with
|
|
25
25
|
* none it throws before reading the stream — and `disk_root` for the
|
|
26
26
|
* over-threshold spill: with none, a body that passes the threshold throws
|
|
27
|
-
* `
|
|
27
|
+
* `FactPayloadTooLargeError`.
|
|
28
28
|
*
|
|
29
29
|
* Every `external_url` the store writes is a `file:<shard>/<rest>` URL into its
|
|
30
30
|
* own disk CAS, and that CAS is the only place `get` reads external bytes from
|
|
@@ -100,8 +100,8 @@ export class PgFactStore {
|
|
|
100
100
|
* BLAKE3 + SHA-256 in one pass, buffer to the embedded threshold, spill to the
|
|
101
101
|
* disk CAS), then inserts the `fact` row by placement — embedded bytes go to
|
|
102
102
|
* the PG `bytes` column, disk-spilled bytes record the `file:` `external_url`.
|
|
103
|
-
* The cap is enforced mid-stream (`
|
|
104
|
-
* stream throws `
|
|
103
|
+
* The cap is enforced mid-stream (`FactPayloadTooLargeError`); a disk-full mid-
|
|
104
|
+
* stream throws `FactStorageFullError`.
|
|
105
105
|
*
|
|
106
106
|
* Refs: explicit `options.refs` are recorded; JSON auto-extraction is NOT
|
|
107
107
|
* attempted (it would need a buffered re-read, defeating the bounded-memory
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
* mis-declared `Content-Length` that the cheap header pre-check can't catch.
|
|
15
15
|
* A consumer route maps this to `413`.
|
|
16
16
|
*/
|
|
17
|
-
export declare class
|
|
17
|
+
export declare class FactPayloadTooLargeError extends Error {
|
|
18
18
|
/** Bytes read before the cap tripped (may exceed `max_bytes` by one chunk). */
|
|
19
19
|
readonly bytes_read: number;
|
|
20
20
|
readonly max_bytes: number;
|
|
@@ -26,13 +26,13 @@ export declare class PayloadTooLargeError extends Error {
|
|
|
26
26
|
* a best-effort free-space preflight can't promise (chunked uploads, TOCTOU
|
|
27
27
|
* races). A consumer route maps this to `507`.
|
|
28
28
|
*/
|
|
29
|
-
export declare class
|
|
29
|
+
export declare class FactStorageFullError extends Error {
|
|
30
30
|
constructor(cause?: unknown);
|
|
31
31
|
}
|
|
32
32
|
/**
|
|
33
33
|
* Whether a thrown value is a Node filesystem `ENOSPC` (no space left on
|
|
34
34
|
* device). Used by the streaming disk write to translate the raw FS error
|
|
35
|
-
* into a `
|
|
35
|
+
* into a `FactStorageFullError`.
|
|
36
36
|
*/
|
|
37
37
|
export declare const is_enospc_error: (err: unknown) => boolean;
|
|
38
38
|
//# sourceMappingURL=fact_store_errors.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fact_store_errors.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/fact_store_errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;GAKG;AACH,qBAAa,
|
|
1
|
+
{"version":3,"file":"fact_store_errors.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/db/fact_store_errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;;;;GAKG;AACH,qBAAa,wBAAyB,SAAQ,KAAK;IAClD,+EAA+E;IAC/E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;gBACf,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;CAMjD;AAED;;;;;GAKG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;gBAClC,KAAK,CAAC,EAAE,OAAO;CAI3B;AAED;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAAI,KAAK,OAAO,KAAG,OAID,CAAC"}
|
|
@@ -14,13 +14,13 @@
|
|
|
14
14
|
* mis-declared `Content-Length` that the cheap header pre-check can't catch.
|
|
15
15
|
* A consumer route maps this to `413`.
|
|
16
16
|
*/
|
|
17
|
-
export class
|
|
17
|
+
export class FactPayloadTooLargeError extends Error {
|
|
18
18
|
/** Bytes read before the cap tripped (may exceed `max_bytes` by one chunk). */
|
|
19
19
|
bytes_read;
|
|
20
20
|
max_bytes;
|
|
21
21
|
constructor(bytes_read, max_bytes) {
|
|
22
22
|
super(`payload too large: read ${bytes_read} bytes, exceeds ${max_bytes} byte limit`);
|
|
23
|
-
this.name = '
|
|
23
|
+
this.name = 'FactPayloadTooLargeError';
|
|
24
24
|
this.bytes_read = bytes_read;
|
|
25
25
|
this.max_bytes = max_bytes;
|
|
26
26
|
}
|
|
@@ -31,16 +31,16 @@ export class PayloadTooLargeError extends Error {
|
|
|
31
31
|
* a best-effort free-space preflight can't promise (chunked uploads, TOCTOU
|
|
32
32
|
* races). A consumer route maps this to `507`.
|
|
33
33
|
*/
|
|
34
|
-
export class
|
|
34
|
+
export class FactStorageFullError extends Error {
|
|
35
35
|
constructor(cause) {
|
|
36
36
|
super('storage_full', cause === undefined ? undefined : { cause });
|
|
37
|
-
this.name = '
|
|
37
|
+
this.name = 'FactStorageFullError';
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
40
|
/**
|
|
41
41
|
* Whether a thrown value is a Node filesystem `ENOSPC` (no space left on
|
|
42
42
|
* device). Used by the streaming disk write to translate the raw FS error
|
|
43
|
-
* into a `
|
|
43
|
+
* into a `FactStorageFullError`.
|
|
44
44
|
*/
|
|
45
45
|
export const is_enospc_error = (err) => typeof err === 'object' &&
|
|
46
46
|
err !== null &&
|