@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.
Files changed (43) hide show
  1. package/dist/db/CLAUDE.md +11 -8
  2. package/dist/db/create_db.d.ts +8 -6
  3. package/dist/db/create_db.d.ts.map +1 -1
  4. package/dist/db/create_db.js +11 -10
  5. package/dist/db/db.d.ts +9 -7
  6. package/dist/db/db.d.ts.map +1 -1
  7. package/dist/db/db.js +5 -4
  8. package/dist/db/db_pglet.d.ts +43 -0
  9. package/dist/db/db_pglet.d.ts.map +1 -0
  10. package/dist/db/db_pglet.js +55 -0
  11. package/dist/db/fact_disk_storage.d.ts +3 -3
  12. package/dist/db/fact_disk_storage.d.ts.map +1 -1
  13. package/dist/db/fact_disk_storage.js +11 -11
  14. package/dist/db/fact_store.d.ts +4 -4
  15. package/dist/db/fact_store.js +3 -3
  16. package/dist/db/fact_store_errors.d.ts +3 -3
  17. package/dist/db/fact_store_errors.d.ts.map +1 -1
  18. package/dist/db/fact_store_errors.js +5 -5
  19. package/dist/testing/CLAUDE.md +17 -18
  20. package/dist/testing/app_server.d.ts +5 -5
  21. package/dist/testing/app_server.d.ts.map +1 -1
  22. package/dist/testing/app_server.js +21 -20
  23. package/dist/testing/cross_backend/default_backend_configs.d.ts +5 -5
  24. package/dist/testing/cross_backend/default_backend_configs.d.ts.map +1 -1
  25. package/dist/testing/cross_backend/default_backend_configs.js +1 -1
  26. package/dist/testing/cross_backend/in_process_setup.d.ts +2 -2
  27. package/dist/testing/cross_backend/in_process_setup.js +3 -3
  28. package/dist/testing/cross_backend/test_cell_gated_create_authorize.js +1 -1
  29. package/dist/testing/cross_backend/testing_reset_actions.d.ts +2 -2
  30. package/dist/testing/cross_backend/testing_reset_actions.js +1 -1
  31. package/dist/testing/cross_backend/ts_spine_backend_config.d.ts +2 -2
  32. package/dist/testing/cross_backend/ts_spine_backend_config.d.ts.map +1 -1
  33. package/dist/testing/db.d.ts +49 -60
  34. package/dist/testing/db.d.ts.map +1 -1
  35. package/dist/testing/db.js +104 -101
  36. package/dist/testing/rate_limiting.d.ts +2 -1
  37. package/dist/testing/rate_limiting.d.ts.map +1 -1
  38. package/dist/testing/rate_limiting.js +2 -2
  39. package/dist/testing/sse_round_trip.d.ts +1 -1
  40. package/dist/testing/sse_round_trip.d.ts.map +1 -1
  41. package/dist/testing/sse_round_trip.js +2 -2
  42. package/dist/testing/stubs.js +1 -1
  43. package/package.json +8 -3
@@ -1,9 +1,5 @@
1
1
  import './assert_dev_env.js';
2
2
  import type { Db } from '../db/db.js';
3
- /**
4
- * CI detection — `CI=true` is set automatically by GitHub Actions, GitLab CI, etc.
5
- */
6
- export declare const IS_CI: boolean;
7
3
  /**
8
4
  * Factory interface for creating test database instances.
9
5
  */
@@ -15,75 +11,83 @@ export interface DbFactory {
15
11
  skip_reason?: string;
16
12
  }
17
13
  /**
18
- * Reset a test database to a clean state by dropping and recreating the public schema.
14
+ * Reset a test database to a clean slate by dropping and recreating the `public` schema.
19
15
  *
20
- * Removes all tables, sequences, indexes, types, and functions.
21
- * The database instance remains usable after reset. Despite the name it issues
22
- * plain SQL, so it also resets the other drivers the test factories hand out.
16
+ * `DROP SCHEMA public CASCADE; CREATE SCHEMA public` in plain SQL, so it resets
17
+ * every driver: the in-memory factories call it on each `create()`, and it is
18
+ * recommended at the start of `init_schema` callbacks for `create_pg_factory`,
19
+ * whose persistent databases accumulate stale DDL across fuz_app versions.
20
+ * Drift-proof — it wipes every table, type, and sequence regardless of
21
+ * namespace, so it needs no upkeep when the schema gains a table. The database
22
+ * instance remains usable after reset.
23
23
  *
24
24
  * @mutates db - drops the `public` schema and recreates it; all rows in all
25
25
  * tables are gone after this returns.
26
26
  */
27
- export declare const reset_pglite: (db: Db) => Promise<void>;
27
+ export declare const reset_public_schema: (db: Db) => Promise<void>;
28
28
  /**
29
- * Builds a `DbFactory` from a schema initializer — `create_pglite_factory`'s own shape.
29
+ * Builds a `DbFactory` from a schema initializer — the shape of every factory builder here.
30
30
  */
31
31
  export type DbFactoryBuilder = (init_schema: (db: Db) => Promise<void>) => DbFactory;
32
32
  /**
33
- * Options for `create_pglite_factory`.
33
+ * Create a PGlite (in-memory) database factory for tests.
34
+ *
35
+ * Always enabled — needs the optional `@electric-sql/pglite` peer installed.
36
+ * Shares one PGlite WASM instance across the PGlite factories this module
37
+ * builds; each `create()` resets the schema via `DROP SCHEMA public CASCADE`
38
+ * instead of paying the cold start again.
39
+ *
40
+ * @param init_schema - callback to initialize the database schema
34
41
  */
35
- export interface CreatePgliteFactoryOptions {
36
- /**
37
- * Whether an installed substitute (`set_substitute_db_factory`) may stand in
38
- * for the PGlite factory at this call site. Defaults to `true`; pass `false`
39
- * where PGlite itself is the subject under test.
40
- */
41
- substitutable?: boolean;
42
- }
42
+ export declare const create_pglite_factory: DbFactoryBuilder;
43
43
  /**
44
- * Install a builder that stands in for `create_pglite_factory`, so suites
45
- * written against PGlite can run against another driver without being edited.
44
+ * Create a pglet-wasm (in-memory) database factory for tests.
45
+ *
46
+ * Always enabled — needs the optional `@fuzdev/pglet-wasm` peer installed.
47
+ * Shares one pglet instance across the pglet-wasm factories this module
48
+ * builds, created with fuz_app's value coercion (`PGLET_COERCION`); each
49
+ * `create()` resets the schema via `DROP SCHEMA public CASCADE`.
46
50
  *
47
- * Injected rather than selected here: the drivers a substitute wraps live in
48
- * test-side code this shipped module cannot import. A call site that passes
49
- * `{substitutable: false}` keeps PGlite regardless. Pass `null` to uninstall.
51
+ * @param init_schema - callback to initialize the database schema
52
+ */
53
+ export declare const create_pglet_wasm_factory: DbFactoryBuilder;
54
+ /**
55
+ * Install the builder `create_default_db_factory` uses, so suites written
56
+ * against the default run against another driver without being edited —
57
+ * `create_pglite_factory` to run them on PGlite. Pass `null` to restore
58
+ * pglet-wasm.
50
59
  *
51
60
  * The slot is read when a factory is built, not when it creates a database,
52
- * so install before the first `create_pglite_factory` call — a vitest
61
+ * so install before the first `create_default_db_factory` call — a vitest
53
62
  * `setupFiles` entry, which runs ahead of every test file's imports, is the
54
63
  * shape fuz_app's own `db` project uses. A factory built earlier (including
55
64
  * the module-level fallback in `testing/app_server.ts`) keeps the driver it
56
65
  * was built with, and uninstalling does not revert it.
57
66
  *
58
- * @param create_factory - the builder to install, or `null` to remove the installed one
67
+ * @param create_factory - the builder to install, or `null` to restore the default
68
+ * @returns the builder this replaced (`null` for pglet-wasm), so a caller can put it back
59
69
  */
60
- export declare const set_substitute_db_factory: (create_factory: DbFactoryBuilder | null) => void;
70
+ export declare const set_default_db_factory: (create_factory: DbFactoryBuilder | null) => DbFactoryBuilder | null;
61
71
  /**
62
- * Create a pglite (in-memory) database factory for tests.
63
- *
64
- * Always enabled — no external dependencies required.
65
- * Shares a single PGlite WASM instance across the PGlite factories this module builds.
66
- * Subsequent `create()` calls reset the schema via `DROP SCHEMA public CASCADE`
67
- * instead of paying the WASM cold-start cost again.
72
+ * Create the default in-memory database factory for tests: pglet-wasm, or the
73
+ * builder `set_default_db_factory` installed.
68
74
  *
69
- * Returns the installed substitute's factory instead when one is installed and
70
- * `options.substitutable` is not `false` — see `set_substitute_db_factory`.
75
+ * The factory fuz_app's own test helpers fall back to when a suite passes none
76
+ * (`create_test_app_server`, `describe_rate_limiting_tests`,
77
+ * `describe_sse_route_tests`). Call `create_pglite_factory` or
78
+ * `create_pglet_wasm_factory` directly to pin a driver.
71
79
  *
72
80
  * @param init_schema - callback to initialize the database schema
73
- * @param options - `substitutable: false` pins this call site to PGlite
74
81
  */
75
- export declare const create_pglite_factory: (init_schema: (db: Db) => Promise<void>, options?: CreatePgliteFactoryOptions) => DbFactory;
82
+ export declare const create_default_db_factory: DbFactoryBuilder;
76
83
  /**
77
84
  * Create a pg (PostgreSQL) database factory for tests.
78
85
  *
79
- * Skipped when `test_url` is not provided.
80
- * Drops `schema_version` before running `init_schema`, forcing migrations
81
- * to re-evaluate against the actual tables. Prevents stale tracker rows
82
- * from skipping migrations when DDL changes between test sessions.
83
- *
84
- * For full clean-slate behavior (recommended), call `drop_auth_schema(db)`
85
- * at the start of `init_schema` before running migrations. This handles
86
- * upstream schema changes that go beyond adding new tables/columns.
86
+ * Skipped when `test_url` is not provided. Each `create()` opens a pool,
87
+ * resets the `public` schema (`reset_public_schema`) and runs `init_schema` —
88
+ * the lifecycle every factory here shares, so a persistent test database never
89
+ * carries stale DDL or tracker rows from an earlier run or another suite's
90
+ * schema. Point `test_url` at a database used only for tests.
87
91
  *
88
92
  * @param init_schema - callback to initialize the database schema
89
93
  * @param test_url - PostgreSQL connection URL (e.g. from `TEST_DATABASE_URL`)
@@ -107,21 +111,6 @@ export declare const auth_truncate_tables: string[];
107
111
  * touch audit logging don't need to truncate it.
108
112
  */
109
113
  export declare const auth_integration_truncate_tables: string[];
110
- /**
111
- * Reset the entire `public` schema for a clean slate before re-migration.
112
- *
113
- * Recommended at the start of `init_schema` callbacks for `create_pg_factory`.
114
- * Persistent test databases accumulate stale DDL across fuz_app versions;
115
- * `DROP SCHEMA public CASCADE; CREATE SCHEMA public` wipes every table, type,
116
- * and sequence regardless of namespace, so migrations always run against a
117
- * truly empty database. Drift-proof — unlike a hand-maintained drop list it
118
- * needs no upkeep when the schema gains a table. Despite the historical name,
119
- * this resets the whole schema, not just auth tables (the only documented use
120
- * is clean-slate re-migration, which always wanted a full reset).
121
- *
122
- * @mutates db - drops and recreates the `public` schema; all tables gone.
123
- */
124
- export declare const drop_auth_schema: (db: Db) => Promise<void>;
125
114
  /**
126
115
  * Create a `describe_db` function bound to specific factories and truncate tables.
127
116
  *
@@ -1 +1 @@
1
- {"version":3,"file":"db.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/db.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AA8B7B,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAMtC;;GAEG;AACH,eAAO,MAAM,KAAK,SAA4B,CAAC;AAE/C;;GAEG;AACH,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,OAAO,CAAC,EAAE,CAAC,CAAC;IAC1B,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY,GAAU,IAAI,EAAE,KAAG,OAAO,CAAC,IAAI,CAGvD,CAAC;AAQF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,WAAW,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,KAAK,SAAS,CAAC;AAErF;;GAEG;AACH,MAAM,WAAW,0BAA0B;IAC1C;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACxB;AAKD;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,yBAAyB,GAAI,gBAAgB,gBAAgB,GAAG,IAAI,KAAG,IAEnF,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,qBAAqB,GACjC,aAAa,CAAC,EAAE,EAAE,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,EACtC,UAAU,0BAA0B,KAClC,SAyBF,CAAC;AAEF;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,iBAAiB,GAC7B,aAAa,CAAC,EAAE,EAAE,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,EACtC,WAAW,MAAM,KACf,SAgEF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,UAQhC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,gCAAgC,UAAyC,CAAC;AAEvF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,gBAAgB,GAAU,IAAI,EAAE,KAAG,OAAO,CAAC,IAAI,CAG3D,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,kBAAkB,GAC9B,WAAW,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,EACvC,iBAAiB,KAAK,CAAC,MAAM,CAAC,KAC5B,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,KAAK,IAAI,CAwBzD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,qBAAqB,GAAI,WAAW,KAAK,CAAC,SAAS,CAAC,KAAG,IAQnE,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,yBAAyB,GACrC,IAAI,EAAE,EACN,OAAO,MAAM,EACb,SAAS,aAAa,CAAC,MAAM,CAAC,KAC5B,OAAO,CAAC,IAAI,CAId,CAAC"}
1
+ {"version":3,"file":"db.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/db.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AA8B7B,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AAQtC;;GAEG;AACH,MAAM,WAAW,SAAS;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,OAAO,CAAC,EAAE,CAAC,CAAC;IAC1B,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,EAAE,OAAO,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,mBAAmB,GAAU,IAAI,EAAE,KAAG,OAAO,CAAC,IAAI,CAG9D,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,WAAW,EAAE,CAAC,EAAE,EAAE,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,KAAK,SAAS,CAAC;AAgDrF;;;;;;;;;GASG;AACH,eAAO,MAAM,qBAAqB,EAAE,gBACqC,CAAC;AAE1E;;;;;;;;;GASG;AACH,eAAO,MAAM,yBAAyB,EAAE,gBACyC,CAAC;AAKlF;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,sBAAsB,GAClC,gBAAgB,gBAAgB,GAAG,IAAI,KACrC,gBAAgB,GAAG,IAIrB,CAAC;AAEF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,yBAAyB,EAAE,gBAC+B,CAAC;AAExE;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,iBAAiB,GAC7B,aAAa,CAAC,EAAE,EAAE,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,EACtC,WAAW,MAAM,KACf,SA6DF,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,UAQhC,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,gCAAgC,UAAyC,CAAC;AAEvF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,kBAAkB,GAC9B,WAAW,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,EACvC,iBAAiB,KAAK,CAAC,MAAM,CAAC,KAC5B,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,IAAI,KAAK,IAAI,CAwBzD,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,qBAAqB,GAAI,WAAW,KAAK,CAAC,SAAS,CAAC,KAAG,IAQnE,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,yBAAyB,GACrC,IAAI,EAAE,EACN,OAAO,MAAM,EACb,SAAS,aAAa,CAAC,MAAM,CAAC,KAC5B,OAAO,CAAC,IAAI,CAId,CAAC"}
@@ -2,129 +2,153 @@ import './assert_dev_env.js';
2
2
  /**
3
3
  * Test database fixtures for parameterized testing.
4
4
  *
5
- * Provides factory builders for creating test databases with pglite (in-memory)
6
- * and pg (PostgreSQL) drivers. Consumer projects provide their own schema
7
- * initialization via `run_migrations` and compose factories into test suites.
5
+ * Provides factory builders for creating test databases with pglet-wasm (the
6
+ * in-memory default), PGlite (in-memory) and pg (PostgreSQL) drivers. Consumer
7
+ * projects provide their own schema initialization via `run_migrations` and
8
+ * compose factories into test suites.
8
9
  *
9
10
  * @example
10
11
  * ```ts
11
- * import {create_pglite_factory, create_pg_factory} from '@fuzdev/fuz_app/testing/db.ts';
12
+ * import {create_default_db_factory, create_pg_factory} from '@fuzdev/fuz_app/testing/db.ts';
12
13
  * import {run_migrations} from '@fuzdev/fuz_app/db/migrate.ts';
13
14
  * import {auth_migration_ns} from '@fuzdev/fuz_app/auth/migrations.ts';
14
15
  *
15
16
  * const init_schema = async (db) => {
16
17
  * await run_migrations(db, [auth_migration_ns]);
17
18
  * };
18
- * const pglite_factory = create_pglite_factory(init_schema);
19
+ * const default_factory = create_default_db_factory(init_schema);
19
20
  * const pg_factory = create_pg_factory(init_schema, process.env.TEST_DATABASE_URL);
20
- * export const db_factories = [pglite_factory, pg_factory];
21
+ * export const db_factories = [default_factory, pg_factory];
21
22
  * ```
22
23
  *
23
24
  * @module
24
25
  */
25
26
  import { describe, beforeAll, beforeEach, afterAll, assert } from 'vitest';
26
- import { to_error_message } from '@fuzdev/fuz_util/error.ts';
27
27
  import { create_pglite_db } from '../db/db_pglite.js';
28
+ import { create_pglet_db_driver, create_pglet_instance } from '../db/db_pglet.js';
28
29
  import { assert_valid_sql_identifier } from '../db/sql_identifier.js';
29
30
  import { create_pg_db, register_pg_type_parsers } from '../db/db_pg.js';
30
31
  import { query_public_columns } from '../db/schema_ready.js';
32
+ import { pg_error_code } from '../db/pg_error.js';
31
33
  /**
32
- * CI detection — `CI=true` is set automatically by GitHub Actions, GitLab CI, etc.
33
- */
34
- export const IS_CI = process.env.CI === 'true';
35
- /**
36
- * Reset a test database to a clean state by dropping and recreating the public schema.
34
+ * Reset a test database to a clean slate by dropping and recreating the `public` schema.
37
35
  *
38
- * Removes all tables, sequences, indexes, types, and functions.
39
- * The database instance remains usable after reset. Despite the name it issues
40
- * plain SQL, so it also resets the other drivers the test factories hand out.
36
+ * `DROP SCHEMA public CASCADE; CREATE SCHEMA public` in plain SQL, so it resets
37
+ * every driver: the in-memory factories call it on each `create()`, and it is
38
+ * recommended at the start of `init_schema` callbacks for `create_pg_factory`,
39
+ * whose persistent databases accumulate stale DDL across fuz_app versions.
40
+ * Drift-proof — it wipes every table, type, and sequence regardless of
41
+ * namespace, so it needs no upkeep when the schema gains a table. The database
42
+ * instance remains usable after reset.
41
43
  *
42
44
  * @mutates db - drops the `public` schema and recreates it; all rows in all
43
45
  * tables are gone after this returns.
44
46
  */
45
- export const reset_pglite = async (db) => {
47
+ export const reset_public_schema = async (db) => {
46
48
  await db.query('DROP SCHEMA public CASCADE');
47
49
  await db.query('CREATE SCHEMA public');
48
50
  };
49
- // Module-level PGlite cache — one instance shared by the PGlite factories this
50
- // module builds, for as long as the module is loaded. Under the `db` project's
51
- // `isolate: false` + `fileParallelism: false` that is the whole run; a project
52
- // that isolates its files gets one per worker instead.
53
- let module_db = null;
54
- // The installed stand-in for `create_pglite_factory`, `null` when none is installed.
55
- let substitute_db_factory = null;
56
51
  /**
57
- * Install a builder that stands in for `create_pglite_factory`, so suites
58
- * written against PGlite can run against another driver without being edited.
52
+ * Build a factory over one module-level instance per driver: the first
53
+ * `create()` creates it, and each `create()` resets its `public` schema and
54
+ * runs `init_schema`, so only the first pays the WASM cold start.
59
55
  *
60
- * Injected rather than selected here: the drivers a substitute wraps live in
61
- * test-side code this shipped module cannot import. A call site that passes
62
- * `{substitutable: false}` keeps PGlite regardless. Pass `null` to uninstall.
56
+ * The instance lives as long as this module stays loaded — under the `db`
57
+ * project's `isolate: false` + `fileParallelism: false` that is the whole run;
58
+ * a project that isolates its files gets one per worker. A promise rather than
59
+ * a value, so two concurrent first `create()` calls build one instance, and a
60
+ * failed first load is the error every later `create()` reports.
61
+ */
62
+ const create_shared_instance_factory = (name, resolve_db, init_schema) => {
63
+ return {
64
+ name,
65
+ skip: false,
66
+ async create() {
67
+ const db = await resolve_db();
68
+ // the instance is shared with every factory of this driver, so it may hold any schema
69
+ await reset_public_schema(db);
70
+ await init_schema(db);
71
+ return db;
72
+ },
73
+ async close() {
74
+ // No-op: the instance is module-level, so it lives as long as this module
75
+ // stays loaded. Nothing frees it earlier.
76
+ }
77
+ };
78
+ };
79
+ // The module-level instances the shared factories hand out, created on first use.
80
+ let pglite_db = null;
81
+ let pglet_wasm_db = null;
82
+ const resolve_pglite_db = () => (pglite_db ??= (async () => {
83
+ const { PGlite } = await import('@electric-sql/pglite');
84
+ return create_pglite_db(new PGlite()).db;
85
+ })());
86
+ const resolve_pglet_wasm_db = () => (pglet_wasm_db ??= create_pglet_instance().then((pglet) => create_pglet_db_driver(pglet).db));
87
+ /**
88
+ * Create a PGlite (in-memory) database factory for tests.
89
+ *
90
+ * Always enabled — needs the optional `@electric-sql/pglite` peer installed.
91
+ * Shares one PGlite WASM instance across the PGlite factories this module
92
+ * builds; each `create()` resets the schema via `DROP SCHEMA public CASCADE`
93
+ * instead of paying the cold start again.
94
+ *
95
+ * @param init_schema - callback to initialize the database schema
96
+ */
97
+ export const create_pglite_factory = (init_schema) => create_shared_instance_factory('pglite', resolve_pglite_db, init_schema);
98
+ /**
99
+ * Create a pglet-wasm (in-memory) database factory for tests.
100
+ *
101
+ * Always enabled — needs the optional `@fuzdev/pglet-wasm` peer installed.
102
+ * Shares one pglet instance across the pglet-wasm factories this module
103
+ * builds, created with fuz_app's value coercion (`PGLET_COERCION`); each
104
+ * `create()` resets the schema via `DROP SCHEMA public CASCADE`.
105
+ *
106
+ * @param init_schema - callback to initialize the database schema
107
+ */
108
+ export const create_pglet_wasm_factory = (init_schema) => create_shared_instance_factory('pglet-wasm', resolve_pglet_wasm_db, init_schema);
109
+ // The builder `create_default_db_factory` uses, `null` for pglet-wasm.
110
+ let default_db_factory_builder = null;
111
+ /**
112
+ * Install the builder `create_default_db_factory` uses, so suites written
113
+ * against the default run against another driver without being edited —
114
+ * `create_pglite_factory` to run them on PGlite. Pass `null` to restore
115
+ * pglet-wasm.
63
116
  *
64
117
  * The slot is read when a factory is built, not when it creates a database,
65
- * so install before the first `create_pglite_factory` call — a vitest
118
+ * so install before the first `create_default_db_factory` call — a vitest
66
119
  * `setupFiles` entry, which runs ahead of every test file's imports, is the
67
120
  * shape fuz_app's own `db` project uses. A factory built earlier (including
68
121
  * the module-level fallback in `testing/app_server.ts`) keeps the driver it
69
122
  * was built with, and uninstalling does not revert it.
70
123
  *
71
- * @param create_factory - the builder to install, or `null` to remove the installed one
124
+ * @param create_factory - the builder to install, or `null` to restore the default
125
+ * @returns the builder this replaced (`null` for pglet-wasm), so a caller can put it back
72
126
  */
73
- export const set_substitute_db_factory = (create_factory) => {
74
- substitute_db_factory = create_factory;
127
+ export const set_default_db_factory = (create_factory) => {
128
+ const previous = default_db_factory_builder;
129
+ default_db_factory_builder = create_factory;
130
+ return previous;
75
131
  };
76
132
  /**
77
- * Create a pglite (in-memory) database factory for tests.
78
- *
79
- * Always enabled — no external dependencies required.
80
- * Shares a single PGlite WASM instance across the PGlite factories this module builds.
81
- * Subsequent `create()` calls reset the schema via `DROP SCHEMA public CASCADE`
82
- * instead of paying the WASM cold-start cost again.
133
+ * Create the default in-memory database factory for tests: pglet-wasm, or the
134
+ * builder `set_default_db_factory` installed.
83
135
  *
84
- * Returns the installed substitute's factory instead when one is installed and
85
- * `options.substitutable` is not `false` — see `set_substitute_db_factory`.
136
+ * The factory fuz_app's own test helpers fall back to when a suite passes none
137
+ * (`create_test_app_server`, `describe_rate_limiting_tests`,
138
+ * `describe_sse_route_tests`). Call `create_pglite_factory` or
139
+ * `create_pglet_wasm_factory` directly to pin a driver.
86
140
  *
87
141
  * @param init_schema - callback to initialize the database schema
88
- * @param options - `substitutable: false` pins this call site to PGlite
89
142
  */
90
- export const create_pglite_factory = (init_schema, options) => {
91
- if (substitute_db_factory && options?.substitutable !== false) {
92
- return substitute_db_factory(init_schema);
93
- }
94
- return {
95
- name: 'pglite',
96
- skip: false,
97
- async create() {
98
- if (module_db) {
99
- await reset_pglite(module_db);
100
- }
101
- else {
102
- const { PGlite } = await import('@electric-sql/pglite');
103
- const pglite = new PGlite();
104
- module_db = create_pglite_db(pglite).db;
105
- }
106
- await init_schema(module_db);
107
- return module_db;
108
- },
109
- async close() {
110
- // No-op: the instance is the module-level cache above, so it lives as long
111
- // as this module stays loaded — under the `db` project's `isolate: false` +
112
- // `fileParallelism: false` that is the whole run. Nothing frees the PGlite
113
- // instance earlier.
114
- }
115
- };
116
- };
143
+ export const create_default_db_factory = (init_schema) => (default_db_factory_builder ?? create_pglet_wasm_factory)(init_schema);
117
144
  /**
118
145
  * Create a pg (PostgreSQL) database factory for tests.
119
146
  *
120
- * Skipped when `test_url` is not provided.
121
- * Drops `schema_version` before running `init_schema`, forcing migrations
122
- * to re-evaluate against the actual tables. Prevents stale tracker rows
123
- * from skipping migrations when DDL changes between test sessions.
124
- *
125
- * For full clean-slate behavior (recommended), call `drop_auth_schema(db)`
126
- * at the start of `init_schema` before running migrations. This handles
127
- * upstream schema changes that go beyond adding new tables/columns.
147
+ * Skipped when `test_url` is not provided. Each `create()` opens a pool,
148
+ * resets the `public` schema (`reset_public_schema`) and runs `init_schema` —
149
+ * the lifecycle every factory here shares, so a persistent test database never
150
+ * carries stale DDL or tracker rows from an earlier run or another suite's
151
+ * schema. Point `test_url` at a database used only for tests.
128
152
  *
129
153
  * @param init_schema - callback to initialize the database schema
130
154
  * @param test_url - PostgreSQL connection URL (e.g. from `TEST_DATABASE_URL`)
@@ -166,17 +190,14 @@ export const create_pg_factory = (init_schema, test_url) => {
166
190
  pool_ref = pool;
167
191
  const { db } = create_pg_db(pool);
168
192
  try {
169
- // Drop schema_version so migrations re-evaluate against the actual
170
- // tables. Prevents stale tracker rows from skipping migrations
171
- // when DDL changes between test sessions. Migrations use
172
- // IF NOT EXISTS guards, so re-running is safe.
173
- await db.query('DROP TABLE IF EXISTS schema_version');
193
+ await reset_public_schema(db);
174
194
  await init_schema(db);
175
195
  }
176
196
  catch (error) {
177
197
  await pool.end();
178
- const msg = to_error_message(error);
179
- if (msg.includes('does not exist')) {
198
+ // 3D000 invalid_catalog_name — the database itself is missing, not
199
+ // something a migration referenced
200
+ if (pg_error_code(error) === '3D000') {
180
201
  const db_name = test_url.split('/').pop()?.split('?')[0] ?? 'test_db';
181
202
  throw new Error(`Database "${db_name}" does not exist. Create it with: createdb ${db_name}`);
182
203
  }
@@ -219,24 +240,6 @@ export const auth_truncate_tables = [
219
240
  * touch audit logging don't need to truncate it.
220
241
  */
221
242
  export const auth_integration_truncate_tables = [...auth_truncate_tables, 'audit_log'];
222
- /**
223
- * Reset the entire `public` schema for a clean slate before re-migration.
224
- *
225
- * Recommended at the start of `init_schema` callbacks for `create_pg_factory`.
226
- * Persistent test databases accumulate stale DDL across fuz_app versions;
227
- * `DROP SCHEMA public CASCADE; CREATE SCHEMA public` wipes every table, type,
228
- * and sequence regardless of namespace, so migrations always run against a
229
- * truly empty database. Drift-proof — unlike a hand-maintained drop list it
230
- * needs no upkeep when the schema gains a table. Despite the historical name,
231
- * this resets the whole schema, not just auth tables (the only documented use
232
- * is clean-slate re-migration, which always wanted a full reset).
233
- *
234
- * @mutates db - drops and recreates the `public` schema; all tables gone.
235
- */
236
- export const drop_auth_schema = async (db) => {
237
- await db.query('DROP SCHEMA public CASCADE');
238
- await db.query('CREATE SCHEMA public');
239
- };
240
243
  /**
241
244
  * Create a `describe_db` function bound to specific factories and truncate tables.
242
245
  *
@@ -16,7 +16,8 @@ export interface RateLimitingTestOptions {
16
16
  /** Optional overrides for `AppServerOptions`. */
17
17
  app_options?: SuiteAppOptions;
18
18
  /**
19
- * Database factories to run tests against. Default: pglite only.
19
+ * Database factories to run tests against. Default: the default factory
20
+ * (`create_default_db_factory`) only.
20
21
  */
21
22
  db_factories?: Array<DbFactory>;
22
23
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"rate_limiting.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/rate_limiting.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AA0B7B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAIvD,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,EAIN,KAAK,SAAS,EACd,MAAM,SAAS,CAAC;AAEjB,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAIhE;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACvC,4CAA4C;IAC5C,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,wDAAwD;IACxD,kBAAkB,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAChE,iDAAiD;IACjD,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B;;OAEG;IACH,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAChC;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,uBAAuB,CAAC;CACxC;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,4BAA4B,GAAI,SAAS,uBAAuB,KAAG,IAqK/E,CAAC"}
1
+ {"version":3,"file":"rate_limiting.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/rate_limiting.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AA0B7B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAIvD,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,EAIN,KAAK,SAAS,EACd,MAAM,SAAS,CAAC;AAEjB,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAIhE;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACvC,4CAA4C;IAC5C,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,wDAAwD;IACxD,kBAAkB,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAChE,iDAAiD;IACjD,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B;;;OAGG;IACH,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAChC;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,uBAAuB,CAAC;CACxC;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,4BAA4B,GAAI,SAAS,uBAAuB,KAAG,IAqK/E,CAAC"}
@@ -25,7 +25,7 @@ import { RateLimiter } from '../rate_limiter.js';
25
25
  import { RateLimitError } from '../http/error_schemas.js';
26
26
  import { auth_migration_ns } from '../auth/migrations.js';
27
27
  import { create_test_app } from './app_server.js';
28
- import { create_pglite_factory, create_describe_db, auth_integration_truncate_tables } from './db.js';
28
+ import { create_default_db_factory, create_describe_db, auth_integration_truncate_tables } from './db.js';
29
29
  import { find_auth_route, assert_rate_limit_retry_after_header } from './integration_helpers.js';
30
30
  import { run_migrations } from '../db/migrate.js';
31
31
  /**
@@ -49,7 +49,7 @@ export const describe_rate_limiting_tests = (options) => {
49
49
  const init_schema = async (db) => {
50
50
  await run_migrations(db, [auth_migration_ns]);
51
51
  };
52
- const factories = options.db_factories ?? [create_pglite_factory(init_schema)];
52
+ const factories = options.db_factories ?? [create_default_db_factory(init_schema)];
53
53
  const describe_db = create_describe_db(factories, auth_integration_truncate_tables);
54
54
  /** Create a tight rate limiter for testing — low attempt count, long window. */
55
55
  const create_test_rate_limiter = () => new RateLimiter({ max_attempts, window_ms: 60_000, cleanup_interval_ms: 0 });
@@ -41,7 +41,7 @@ export interface SseRouteTestOptions {
41
41
  create_route_specs: (ctx: AppServerContext) => Array<RouteSpec>;
42
42
  /** Optional overrides for `AppServerOptions`. */
43
43
  app_options?: SuiteAppOptions;
44
- /** Database factories to run tests against. Default: pglite only. */
44
+ /** Database factories to run tests against. Default: the default factory (`create_default_db_factory`) only. */
45
45
  db_factories?: Array<DbFactory>;
46
46
  /**
47
47
  * Backend audit event callback — threaded to `create_test_app_server`.
@@ -1 +1 @@
1
- {"version":3,"file":"sse_round_trip.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/sse_round_trip.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAmB7B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,oBAAoB,CAAC;AAGrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAGjE,OAAO,EAEN,KAAK,eAAe,EACpB,KAAK,OAAO,EACZ,KAAK,WAAW,EAChB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAyB,KAAK,SAAS,EAAE,MAAM,SAAS,CAAC;AAEhE,OAAO,EAIN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAO1B,gDAAgD;AAChD,MAAM,WAAW,gBAAgB;IAChC,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,OAAO,EAAE,CAAC,GAAG,EAAE;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,WAAW,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7E;;;OAGG;IACH,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/B;;;;;OAKG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,8CAA8C;AAC9C,MAAM,WAAW,mBAAmB;IACnC,4CAA4C;IAC5C,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,qDAAqD;IACrD,kBAAkB,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAChE,iDAAiD;IACjD,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,qEAAqE;IACrE,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAChC;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAChD;;;;;;;;;;;;OAYG;IACH,aAAa,EAAE,uBAAuB,CAAC;IACvC,8BAA8B;IAC9B,MAAM,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAC;CAChC;AAmDD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,wBAAwB,GAAI,SAAS,mBAAmB,KAAG,IAkIvE,CAAC"}
1
+ {"version":3,"file":"sse_round_trip.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/testing/sse_round_trip.ts"],"names":[],"mappings":"AAAA,OAAO,qBAAqB,CAAC;AAmB7B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,oBAAoB,CAAC;AAGrE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAGjE,OAAO,EAEN,KAAK,eAAe,EACpB,KAAK,OAAO,EACZ,KAAK,WAAW,EAChB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAA6B,KAAK,SAAS,EAAE,MAAM,SAAS,CAAC;AAEpE,OAAO,EAIN,KAAK,uBAAuB,EAC5B,MAAM,kBAAkB,CAAC;AAO1B,gDAAgD;AAChD,MAAM,WAAW,gBAAgB;IAChC,yEAAyE;IACzE,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,OAAO,EAAE,CAAC,GAAG,EAAE;QAAE,QAAQ,EAAE,OAAO,CAAC;QAAC,OAAO,EAAE,WAAW,CAAA;KAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7E;;;OAGG;IACH,WAAW,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAC/B;;;;;OAKG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,8CAA8C;AAC9C,MAAM,WAAW,mBAAmB;IACnC,4CAA4C;IAC5C,eAAe,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IACxC,qDAAqD;IACrD,kBAAkB,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,KAAK,CAAC,SAAS,CAAC,CAAC;IAChE,iDAAiD;IACjD,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,gHAAgH;IAChH,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC;IAChC;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAChD;;;;;;;;;;;;OAYG;IACH,aAAa,EAAE,uBAAuB,CAAC;IACvC,8BAA8B;IAC9B,MAAM,EAAE,KAAK,CAAC,gBAAgB,CAAC,CAAC;CAChC;AAmDD;;;;;;;;;;GAUG;AACH,eAAO,MAAM,wBAAwB,GAAI,SAAS,mBAAmB,KAAG,IAkIvE,CAAC"}
@@ -18,7 +18,7 @@ import { SSE_CONNECTED_COMMENT } from '../realtime/sse_constants.js';
18
18
  import { ROLE_ADMIN } from '../auth/role_schema.js';
19
19
  import { create_audit_emitter } from '../auth/audit_emitter.js';
20
20
  import { create_test_app } from './app_server.js';
21
- import { create_pglite_factory } from './db.js';
21
+ import { create_default_db_factory } from './db.js';
22
22
  import { find_route_spec, pick_auth_headers } from './integration_helpers.js';
23
23
  import { rpc_call, require_rpc_endpoint_path, resolve_rpc_endpoints_for_setup } from './rpc_helpers.js';
24
24
  import { run_migrations } from '../db/migrate.js';
@@ -74,7 +74,7 @@ export const describe_sse_route_tests = (options) => {
74
74
  const init_schema = async (db) => {
75
75
  await run_migrations(db, [auth_migration_ns]);
76
76
  };
77
- const factories = options.db_factories ?? [create_pglite_factory(init_schema)];
77
+ const factories = options.db_factories ?? [create_default_db_factory(init_schema)];
78
78
  for (const factory of factories) {
79
79
  const describe_fn = factory.skip ? describe.skip : describe;
80
80
  describe_fn(`SSE validation (${factory.name})`, () => {
@@ -160,7 +160,7 @@ export const create_stub_app_deps = () => ({
160
160
  * @param options - the deps and `close` to use in place of the defaults
161
161
  */
162
162
  export const create_stub_app_backend = (options) => ({
163
- db_type: 'pglite-memory',
163
+ db_type: 'pglet-memory',
164
164
  db_name: 'test',
165
165
  migration_results: [],
166
166
  close: options?.close ?? (async () => { }),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fuzdev/fuz_app",
3
- "version": "0.132.1",
3
+ "version": "0.134.0",
4
4
  "description": "fullstack app library",
5
5
  "glyph": "🗝",
6
6
  "logo": "logo.svg",
@@ -35,6 +35,7 @@
35
35
  "@fuzdev/blake3-wasm": ">=0.2.0",
36
36
  "@fuzdev/fuz_css": ">=0.65.0",
37
37
  "@fuzdev/fuz_util": ">=0.70.0",
38
+ "@fuzdev/pglet-wasm": ">=0.1.1",
38
39
  "@hono/bun": ">=1",
39
40
  "@hono/deno": ">=1",
40
41
  "@hono/node-server": ">=1",
@@ -55,6 +56,9 @@
55
56
  "@fuzdev/fuz_css": {
56
57
  "optional": true
57
58
  },
59
+ "@fuzdev/pglet-wasm": {
60
+ "optional": true
61
+ },
58
62
  "@hono/bun": {
59
63
  "optional": true
60
64
  },
@@ -86,12 +90,13 @@
86
90
  "devDependencies": {
87
91
  "@electric-sql/pglite": "^0.5.8",
88
92
  "@fuzdev/blake3-wasm": "^0.2.0",
89
- "@fuzdev/fuz_code": "^0.50.0",
93
+ "@fuzdev/fuz_code": "^0.52.1",
90
94
  "@fuzdev/fuz_css": "^0.66.1",
91
95
  "@fuzdev/fuz_ui": "^0.213.0",
92
96
  "@fuzdev/fuz_util": "^0.72.0",
93
97
  "@fuzdev/gro": "^0.216.0",
94
98
  "@fuzdev/mdz": "^0.4.0",
99
+ "@fuzdev/pglet-wasm": "^0.1.1",
95
100
  "@hono/bun": "^1.0.1",
96
101
  "@hono/deno": "^1.0.3",
97
102
  "@hono/node-server": "^1.19.14",
@@ -116,7 +121,7 @@
116
121
  "pg": "^8.20.0",
117
122
  "svelte": "^5.57.2",
118
123
  "svelte-check": "^4.7.6",
119
- "svelte-docinfo": "^0.8.1",
124
+ "svelte-docinfo": "^0.9.0",
120
125
  "svelte2tsx": "^0.7.52",
121
126
  "tslib": "^2.8.1",
122
127
  "typescript": "^6.0.3",