@happyvertical/smrt-core 0.51.32 → 0.51.34

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 (172) hide show
  1. package/agents/build-knowledge.md +13 -0
  2. package/dist/__tests__/fixtures/collection-coverage-fixtures.d.ts +8 -0
  3. package/dist/__tests__/fixtures/inheritance-resolver-fixtures.d.ts +9 -0
  4. package/dist/__tests__/fixtures/inheritance-test-classes.d.ts +5 -0
  5. package/dist/__tests__/fixtures/object-ai-memory-fixtures.d.ts +10 -0
  6. package/dist/__typechecks__/collection-read-plan.d.ts +2 -2
  7. package/dist/adapters/ai-usage.d.ts +5 -2
  8. package/dist/adapters/cost-rates.d.ts +1 -1
  9. package/dist/adapters/metrics.d.ts +7 -1
  10. package/dist/adapters/pubsub.d.ts +7 -1
  11. package/dist/cascade.d.ts +69 -3
  12. package/dist/change-feed-authz.d.ts +85 -2
  13. package/dist/change-feed.d.ts +133 -2
  14. package/dist/change-signals.d.ts +66 -1
  15. package/dist/child-accessors.d.ts +39 -1
  16. package/dist/class.d.ts +8 -8
  17. package/dist/collection-cache.d.ts +47 -1
  18. package/dist/collection-read-plan.d.ts +3 -3
  19. package/dist/collection.d.ts +4 -3
  20. package/dist/config.d.ts +15 -6
  21. package/dist/consumer-plugin/index.d.ts +7 -3
  22. package/dist/consumer-plugin/index.d.ts.map +1 -1
  23. package/dist/consumer-plugin/index.js +2 -0
  24. package/dist/consumer-plugin/index.js.map +1 -1
  25. package/dist/data-query.d.ts +12 -1
  26. package/dist/database.d.ts +10 -2
  27. package/dist/decisions.d.ts +9 -2
  28. package/dist/decorators/index.d.ts +11 -5
  29. package/dist/dispatch/bus.d.ts +27 -2
  30. package/dist/dispatch/collections/DispatchSubscriptions.d.ts +7 -2
  31. package/dist/dispatch/collections/Dispatches.d.ts +8 -3
  32. package/dist/dispatch/models/Dispatch.d.ts +7 -1
  33. package/dist/dispatch/types.d.ts +7 -2
  34. package/dist/embedded-write-queue.d.ts +1 -1
  35. package/dist/embeddings/provider.d.ts +8 -1
  36. package/dist/embeddings/storage.d.ts +8 -2
  37. package/dist/filesystem-loader.d.ts +16 -1
  38. package/dist/generators/changes-route.d.ts +34 -1
  39. package/dist/generators/custom-action.d.ts +10 -2
  40. package/dist/generators/events-route.d.ts +41 -4
  41. package/dist/generators/mcp-runtime-template.d.ts +13 -2
  42. package/dist/generators/mcp.d.ts +6 -1
  43. package/dist/generators/rest.d.ts +10 -5
  44. package/dist/generators/tool-schema.d.ts +1 -1
  45. package/dist/hierarchical.d.ts +37 -1
  46. package/dist/interceptors.d.ts +45 -1
  47. package/dist/junction.d.ts +24 -0
  48. package/dist/knowledge-config.d.ts +1 -1
  49. package/dist/knowledge-discovery.d.ts +2 -25
  50. package/dist/knowledge-discovery.d.ts.map +1 -1
  51. package/dist/knowledge-discovery.js +1 -53
  52. package/dist/knowledge-graph.d.ts +2 -94
  53. package/dist/knowledge-graph.d.ts.map +1 -1
  54. package/dist/knowledge-graph.js +1 -267
  55. package/dist/knowledge.d.ts +4 -23
  56. package/dist/knowledge.d.ts.map +1 -1
  57. package/dist/knowledge.js +3 -52
  58. package/dist/knowledge.js.map +1 -1
  59. package/dist/learning/memory.d.ts +21 -1
  60. package/dist/manifest/generator.d.ts +5 -1
  61. package/dist/manifest/index.d.ts +5 -1
  62. package/dist/manifest/manager.d.ts +1 -1
  63. package/dist/manifest/manifest-loader.d.ts +24 -2
  64. package/dist/manifest/sources/composite.d.ts +17 -1
  65. package/dist/manifest/sources/embedded.d.ts +10 -1
  66. package/dist/manifest/sources/explicit-paths.d.ts +13 -1
  67. package/dist/manifest/sources/fallback.d.ts +15 -1
  68. package/dist/manifest/sources/local-test.d.ts +10 -1
  69. package/dist/manifest/sources/static.d.ts +12 -1
  70. package/dist/manifest/sources/test.d.ts +9 -1
  71. package/dist/manifest/sources/types.d.ts +7 -1
  72. package/dist/manifest/static-manifest.d.ts +6 -1
  73. package/dist/manifest/static-manifest.js +1 -1
  74. package/dist/manifest/static-manifest.js.map +1 -1
  75. package/dist/manifest/store.d.ts +22 -3
  76. package/dist/manifest/store.js +1 -1
  77. package/dist/manifest.json +1 -1
  78. package/dist/migrations/backfill-tracker.d.ts +15 -1
  79. package/dist/migrations/differ.d.ts +8 -2
  80. package/dist/migrations/framework-base-tables.d.ts +57 -2
  81. package/dist/migrations/generator.d.ts +8 -2
  82. package/dist/migrations/integer-width.d.ts +10 -2
  83. package/dist/migrations/minor-units.d.ts +40 -1
  84. package/dist/migrations/null-equal-indexes.d.ts +3 -2
  85. package/dist/migrations/orchestrate.d.ts +15 -3
  86. package/dist/migrations/sqlite-rebuild.d.ts +67 -2
  87. package/dist/migrations/tracker.d.ts +9 -3
  88. package/dist/migrations/types.d.ts +7 -2
  89. package/dist/object.d.ts +7 -6
  90. package/dist/polymorphic-association.d.ts +44 -1
  91. package/dist/postgres-permissions.d.ts +1 -1
  92. package/dist/prebuild/index.d.ts +5 -1
  93. package/dist/query-bounds.d.ts +26 -0
  94. package/dist/registry/cache-config.d.ts +10 -1
  95. package/dist/registry/class-registration.d.ts +10 -2
  96. package/dist/registry/collection-resolution.d.ts +1 -1
  97. package/dist/registry/embedding-manager.d.ts +9 -1
  98. package/dist/registry/inheritance-resolver.d.ts +8 -3
  99. package/dist/registry/manifest-field-merge.d.ts +2 -2
  100. package/dist/registry/name-resolver.d.ts +22 -2
  101. package/dist/registry/relationship-graph.d.ts +9 -1
  102. package/dist/registry/schema-builder.d.ts +8 -3
  103. package/dist/registry/shared-state.d.ts +12 -2
  104. package/dist/registry/types.d.ts +15 -7
  105. package/dist/registry/validator.d.ts +10 -2
  106. package/dist/registry.d.ts +40 -11
  107. package/dist/relationship-loader.d.ts +1 -1
  108. package/dist/run-once.d.ts +110 -1
  109. package/dist/runtime/client.d.ts +4 -1
  110. package/dist/runtime/server.d.ts +5 -2
  111. package/dist/scanner/import-scanner.d.ts +1 -1
  112. package/dist/scanner/manifest-generator.d.ts +4 -1
  113. package/dist/scanner/types.d.ts +4 -1
  114. package/dist/schema/code-generator.d.ts +6 -2
  115. package/dist/schema/column-data-probes.d.ts +27 -2
  116. package/dist/schema/ddl/base-strategy.d.ts +8 -2
  117. package/dist/schema/ddl/duckdb-strategy.d.ts +14 -2
  118. package/dist/schema/ddl/index.d.ts +2 -2
  119. package/dist/schema/ddl/json-duckdb-strategy.d.ts +10 -2
  120. package/dist/schema/ddl/materialize-manifest.d.ts +1 -1
  121. package/dist/schema/ddl/null-equal-index.d.ts +1 -1
  122. package/dist/schema/ddl/postgres-strategy.d.ts +12 -2
  123. package/dist/schema/ddl/sqlite-strategy.d.ts +12 -2
  124. package/dist/schema/ddl/types.d.ts +10 -1
  125. package/dist/schema/foreign-key-ddl.d.ts +2 -2
  126. package/dist/schema/foreign-key-orphan-report.d.ts +25 -3
  127. package/dist/schema/foreign-key-planner.d.ts +2 -2
  128. package/dist/schema/foreign-key-policy.d.ts +1 -1
  129. package/dist/schema/generator.d.ts +7 -3
  130. package/dist/schema/index-utils.d.ts +11 -2
  131. package/dist/schema/live-parity.d.ts +27 -3
  132. package/dist/schema/manifest-schema.d.ts +21 -2
  133. package/dist/schema/schema-aggregator.d.ts +35 -2
  134. package/dist/schema/schema-manager.d.ts +13 -4
  135. package/dist/schema/system-table-shapes.d.ts +20 -1
  136. package/dist/schema/table-verifier.d.ts +1 -1
  137. package/dist/schema/text-cast-probe.d.ts +24 -1
  138. package/dist/schema/utils.d.ts +13 -4
  139. package/dist/schema/uuid-convergence.d.ts +32 -1
  140. package/dist/signals/bus.d.ts +8 -2
  141. package/dist/signals/sanitizer.d.ts +7 -1
  142. package/dist/smrt-knowledge.json +8 -9
  143. package/dist/system/bootstrap.d.ts +2 -1
  144. package/dist/system/compatibility.d.ts +1 -1
  145. package/dist/system/diagnostics.d.ts +17 -2
  146. package/dist/system/retention.d.ts +46 -1
  147. package/dist/system/schema.d.ts +7 -1
  148. package/dist/system-fields.d.ts +9 -1
  149. package/dist/test-utils.d.ts +7 -1
  150. package/dist/testing/database.d.ts +18 -1
  151. package/dist/testing/notifications-stub.d.ts +15 -1
  152. package/dist/tools/tool-executor.d.ts +6 -1
  153. package/dist/tools/tool-generator.d.ts +8 -2
  154. package/dist/utils/json.d.ts +9 -1
  155. package/dist/utils/qualified-names.d.ts +10 -1
  156. package/dist/utils/scanner-module.d.ts +2 -2
  157. package/dist/utils.d.ts +1 -1
  158. package/dist/vite-plugin/api-client-entries.d.ts +9 -1
  159. package/dist/vite-plugin/changes-route.d.ts +33 -2
  160. package/dist/vite-plugin/dev-plane-route.d.ts +12 -1
  161. package/dist/vite-plugin/events-route.d.ts +37 -2
  162. package/dist/vite-plugin/generated-client.d.ts +9 -1
  163. package/dist/vite-plugin/index.d.ts +9 -5
  164. package/dist/vite-plugin/resources-route.d.ts +82 -1
  165. package/dist/vite-plugin/sveltekit-generator.d.ts +8 -4
  166. package/dist/vite-plugin/sveltekit-route-coordinator.d.ts +3 -3
  167. package/dist/vite-plugin/sync-apply-route.d.ts +19 -2
  168. package/dist/vite-plugin/web-collections.d.ts +25 -2
  169. package/dist/vite-plugin/worker-registration.d.ts +21 -1
  170. package/package.json +7 -8
  171. package/dist/knowledge-discovery.js.map +0 -1
  172. package/dist/knowledge-graph.js.map +0 -1
@@ -1,4 +1,18 @@
1
- import { DatabaseInterface } from '@happyvertical/sql';
1
+ /**
2
+ * Tracks application-specific data backfills (not schema migrations).
3
+ *
4
+ * Sits next to `MigrationTracker` but is intentionally minimal — backfills
5
+ * have no checksum, no rollback semantics, no DDL. They're "this data
6
+ * correction has run, don't run it again" markers, keyed by a stable
7
+ * backfill name the app chooses.
8
+ *
9
+ * Backed by the `_smrt_backfills` system table (see
10
+ * `../system/schema.ts`). The table is created lazily on first use —
11
+ * every public method (`isApplied`, `recordApplied`, `runIfPending`,
12
+ * `listApplied`) awaits `initialize()` itself, so consumers never need
13
+ * to call `initialize()` explicitly.
14
+ */
15
+ import type { DatabaseInterface } from '@happyvertical/sql';
2
16
  export interface BackfillTrackerOptions {
3
17
  db: DatabaseInterface;
4
18
  }
@@ -1,5 +1,11 @@
1
- import { ColumnDefinition, SchemaChange, SchemaDefinition, SchemaDiff, SQLDataType } from '../schema/types.js';
2
- import { DatabaseInterface, SqlTableSchemaInfo } from './types.js';
1
+ /**
2
+ * Schema Differ
3
+ *
4
+ * Compares manifest schemas to database schemas and generates
5
+ * a SchemaDiff with the differences.
6
+ */
7
+ import type { ColumnDefinition, SchemaChange, SchemaDefinition, SchemaDiff, SQLDataType } from '../schema/types.js';
8
+ import type { DatabaseInterface, SqlTableSchemaInfo } from './types.js';
3
9
  /**
4
10
  * `mismatch.actual` of the manual change reported when a required column
5
11
  * could not be added to a populated table (#3008): the column is absent.
@@ -1,5 +1,60 @@
1
- import { DatabaseInterface } from '@happyvertical/sql';
2
- import { DatabaseEngine } from '../schema/ddl/types.js';
1
+ /**
2
+ * One-time remediation for the five orphaned framework-base tables (#2647).
3
+ *
4
+ * #2644 stopped `getAllSchemasAsDefinitions()` from planning a table for
5
+ * SMRT's abstract framework-base classes (`SmrtObject`, `SmrtClass`,
6
+ * `SmrtCollection`, `SmrtHierarchical`, `SmrtPolymorphicAssociation`), but it
7
+ * does not remove the ones a pre-fix `db:migrate` already created. Any
8
+ * deployment that ran `db:migrate` before that fix has all five tables, and
9
+ * the differ now reports them as permanent orphans (#2369's
10
+ * `includeDroppedTables` stays `false` on purpose — see below).
11
+ *
12
+ * This module is a narrow, named remediation, deliberately **not** a change
13
+ * to the general differ: `SchemaDiff.orphan_tables` already reports orphan
14
+ * tables, and `includeDroppedTables` (default `false`, both call sites pass
15
+ * it explicitly) is the opt-in for the executable `DROP TABLE`. That default
16
+ * must stay `false` — flipping it globally would make `db:migrate` drop *any*
17
+ * table absent from the manifest, which for a consumer with hand-managed or
18
+ * legacy tables is unacceptable data loss. Dropping only these five specific,
19
+ * hand-typed names is safe *because* nothing but the retired base-class
20
+ * planning path could ever have created them; a general orphan drop is not.
21
+ *
22
+ * Safety model, in order:
23
+ * 1. {@link FRAMEWORK_BASE_TABLE_NAMES} is a literal, hand-typed list. It is
24
+ * never derived from a differ orphan report or any other dynamic source —
25
+ * doing so would recreate the dangerous global-drop path by another route.
26
+ * 2. {@link planFrameworkBaseTableDrop} is read-only. For every name in the
27
+ * list that exists live, it verifies the table has *only* that table's
28
+ * expected columns — the universal `id`/`slug`/`context`/`created_at`/
29
+ * `updated_at` base for three of the five, extended with the real fields
30
+ * `SmrtHierarchical`/`SmrtPolymorphicAssociation` themselves declare for
31
+ * `smrt_hierarchicals`/`smrt_polymorphic_associations` (see
32
+ * {@link EXPECTED_COLUMN_BUCKETS_BY_TABLE}) — with a plausible type for
33
+ * each, is referenced by no foreign key anywhere in the live database,
34
+ * and is empty. Any live table missing that shape — e.g. a consumer's
35
+ * own, unrelated table that happens to share one of these five names —
36
+ * is reported as unsafe and dropped nothing.
37
+ * 3. {@link dropFrameworkBaseTables} refuses to run against a plan that is
38
+ * not `safe`, locks every PostgreSQL target `IN ACCESS EXCLUSIVE MODE`
39
+ * (a plain `SELECT COUNT(*)` alone would not block a concurrent writer),
40
+ * and then re-verifies shape, type, and emptiness — not just the row
41
+ * count — inside that same bounded transaction immediately before
42
+ * dropping anything. A table rewritten or replaced between planning and
43
+ * execution therefore still stops the whole batch, not just a row-count
44
+ * race. Foreign keys are checked at planning time only. On PostgreSQL, a
45
+ * foreign key added afterward is still caught — its FK enforcement is
46
+ * dependency-based, so `DROP TABLE` refuses when a real dependent
47
+ * exists. This does **not** hold on SQLite/DuckDB: SQLite's `DROP TABLE`
48
+ * only enforces against the rows actually being removed, so an empty
49
+ * parent (exactly this function's precondition) drops cleanly past a
50
+ * real foreign key, and DuckDB's adapter cannot even see the reference
51
+ * at plan time (see {@link qualifyIdentifier}'s doc comment). No data is
52
+ * lost either way — the residual risk on those two engines is a
53
+ * dangling reference, not data loss, confined to a narrow window a
54
+ * one-time operator-run command makes unlikely in practice.
55
+ */
56
+ import type { DatabaseInterface } from '@happyvertical/sql';
57
+ import type { DatabaseEngine } from '../schema/ddl/types.js';
3
58
  /**
4
59
  * The exact five orphaned framework-base tables #2644 stopped planning.
5
60
  *
@@ -1,5 +1,11 @@
1
- import { MigrationDefinition, SchemaDiff } from '../schema/types.js';
2
- import { DatabaseEngine } from './types.js';
1
+ /**
2
+ * Migration Generator
3
+ *
4
+ * Generates migration files from schema diffs.
5
+ * Supports both SQL and TypeScript formats.
6
+ */
7
+ import type { MigrationDefinition, SchemaDiff } from '../schema/types.js';
8
+ import type { DatabaseEngine } from './types.js';
3
9
  /**
4
10
  * Options for migration generation
5
11
  */
@@ -1,5 +1,13 @@
1
- import { DatabaseInterface } from '@happyvertical/sql';
2
- import { SchemaDefinition } from '../schema/types.js';
1
+ /**
2
+ * Explicit one-time widening for deployments created before #2373.
3
+ *
4
+ * Fresh PostgreSQL and DuckDB schemas now materialize SMRT's abstract
5
+ * `INTEGER` as `BIGINT`. The migration differ deliberately treats int4 and
6
+ * int8 as equivalent, so existing deployments need this separate, operator
7
+ * initiated maintenance-window migration rather than an automatic repair.
8
+ */
9
+ import type { DatabaseInterface } from '@happyvertical/sql';
10
+ import type { SchemaDefinition } from '../schema/types.js';
3
11
  /** A table and its SMRT-owned integer columns. */
4
12
  export interface IntegerWidthTarget {
5
13
  table: string;
@@ -1,4 +1,43 @@
1
- import { DatabaseInterface } from './types.js';
1
+ /**
2
+ * Money-column rescale: floating-point major units → integer minor units (#2401).
3
+ *
4
+ * SMRT's rule is that money is exact and is stored as **integer minor units**
5
+ * at an application-defined scale — `$19.99` is `1999` at a cents scale.
6
+ * Packages that predate the rule
7
+ * declared their money fields `= 0.0`, which compiles to a floating-point
8
+ * column holding *major* units. Flipping the declaration to `= 0` changes the
9
+ * column type, and REAL→INTEGER is deliberately **not** one of the differ's
10
+ * whitelisted upgrades: an automatic `ALTER … TYPE BIGINT` would truncate
11
+ * `19.99` to `19`, silently destroying minor units on every row.
12
+ *
13
+ * So the conversion is an explicit, opt-in migration with two halves:
14
+ *
15
+ * 1. {@link preflightMinorUnitsRescale} — read-only. Reports, per column,
16
+ * whether it still needs converting, and lists the rows that would lose
17
+ * information: values whose scaled form is not a whole number (a half-cent
18
+ * that has to be rounded away) and values that exceed JavaScript's safe
19
+ * integer range once multiplied by the scale. Run it against a production
20
+ * snapshot and
21
+ * read the summary before converting anything.
22
+ * 2. {@link rescaleMoneyColumnsToMinorUnits} — the conversion itself, guarded
23
+ * by a {@link BackfillTracker} marker so re-running it can never multiply a
24
+ * table by 100 twice.
25
+ *
26
+ * Per-engine behaviour:
27
+ *
28
+ * | Engine | Column type | Values |
29
+ * | --- | --- | --- |
30
+ * | PostgreSQL | `ALTER COLUMN … TYPE BIGINT USING round(col * scale)` | converted by the cast |
31
+ * | DuckDB | `ALTER COLUMN … TYPE BIGINT USING round(col * scale)` | converted by the cast |
32
+ * | SQLite | **not changed here** — SQLite cannot alter a column's declared type in place | rescaled with an `UPDATE`, values become exact integers |
33
+ *
34
+ * SQLite's declared type only sets an affinity, so a rescaled column already
35
+ * behaves as integer minor units; bringing the *declaration* into line needs
36
+ * the table-rebuild path (#2370). The result flags that with
37
+ * {@link MinorUnitsRescaleResult.declaredTypeChangePending} rather than
38
+ * pretending the column type moved.
39
+ */
40
+ import type { DatabaseInterface } from './types.js';
2
41
  /** A table and the money columns on it that must move to minor units. */
3
42
  export interface MoneyColumnTarget {
4
43
  /** Physical table name, e.g. `payments`. */
@@ -1,5 +1,6 @@
1
- import { DatabaseInterface } from '@happyvertical/sql';
2
- import { SchemaDefinition } from '../schema/types.js';
1
+ /** Explicit, atomic maintenance upgrade of framework-owned nullable conflict indexes. */
2
+ import type { DatabaseInterface } from '@happyvertical/sql';
3
+ import type { SchemaDefinition } from '../schema/types.js';
3
4
  export interface NullEqualIndexTarget {
4
5
  table: string;
5
6
  index: string;
@@ -1,6 +1,18 @@
1
- import { DatabaseInterface } from '@happyvertical/sql';
2
- import { DatabaseEngine } from '../schema/ddl/types.js';
3
- import { MigrationResult, SchemaChange } from '../schema/types.js';
1
+ /**
2
+ * High-level "make my SMRT app's schema match its database" orchestration.
3
+ *
4
+ * Wraps `ObjectRegistry.getAllSchemasAsDefinitions()` → `generateSchemaDiff`
5
+ * → `MigrationTracker.applyAll`. Apps that just want to run pending
6
+ * schema changes call `migrateSmrtSchemas({ db, packageName, version })`
7
+ * and don't have to assemble the migration definition by hand.
8
+ *
9
+ * The migration name is timestamped, so re-running on an up-to-date
10
+ * database is a no-op (the diff is empty, no statements are generated,
11
+ * `applied: false` is returned).
12
+ */
13
+ import type { DatabaseInterface } from '@happyvertical/sql';
14
+ import type { DatabaseEngine } from '../schema/ddl/types.js';
15
+ import type { MigrationResult, SchemaChange } from '../schema/types.js';
4
16
  import { generateSchemaDiff } from './differ.js';
5
17
  export interface MigrateSmrtSchemasOptions {
6
18
  db: DatabaseInterface;
@@ -1,5 +1,70 @@
1
- import { SchemaChange, SQLDataType } from '../schema/types.js';
2
- import { DatabaseInterface } from './types.js';
1
+ /**
2
+ * SQLite table-rebuild migrations (issue #2370)
3
+ *
4
+ * SQLite has no `ALTER TABLE ... ALTER COLUMN ... TYPE`. Before this module
5
+ * every type-bucket change on SQLite (the canonical one being a numeric
6
+ * default edited from `0` to `0.0`, i.e. INTEGER → REAL) turned into an
7
+ * advisory differ comment, which `db:migrate` classifies as
8
+ * *manual intervention* and exits 1 for — forever, because nothing in the
9
+ * toolchain could ever perform the change.
10
+ *
11
+ * This module turns that comment into the executable rebuild SQLite's own
12
+ * documentation prescribes ("Making Other Kinds Of Table Schema Changes",
13
+ * lang_altertable.html):
14
+ *
15
+ * 1. `PRAGMA defer_foreign_keys = ON` — defers foreign-key enforcement to
16
+ * COMMIT so the window where the table does not exist cannot raise. It is
17
+ * honored *inside* a transaction (unlike `PRAGMA foreign_keys`, which is a
18
+ * silent no-op there) and resets itself at COMMIT/ROLLBACK.
19
+ * 2. Create a new table under a reserved `_smrt_rebuild_` name carrying the
20
+ * target shape.
21
+ * 3. Copy every row across.
22
+ * 4. Drop the original table.
23
+ * 5. Rename the new table into its place, with `PRAGMA legacy_alter_table`
24
+ * ON for the rename itself (see {@link buildSqliteRebuildStatements}).
25
+ * 6. Recreate the indexes and triggers that died with the original table.
26
+ *
27
+ * The whole plan is a plain statement list, so it is executed by the
28
+ * `MigrationTracker` inside the same transaction as the rest of the batch:
29
+ * a failure anywhere rolls the table back to its original shape and contents.
30
+ *
31
+ * ## The target shape comes from the live DDL, not from the manifest
32
+ *
33
+ * The new table is the *original* `CREATE TABLE` text with only the drifted
34
+ * columns' type tokens replaced. That deliberately preserves everything the
35
+ * manifest does not model or does not own here: columns the manifest has
36
+ * dropped (SMRT is additive — a rebuild must not become an implicit
37
+ * `DROP COLUMN`), table-level constraints, `CHECK`s, collations, and table
38
+ * options such as `WITHOUT ROWID`. The `add_column` changes in the same batch
39
+ * still run their own `ALTER TABLE ... ADD COLUMN`, against the rebuilt table
40
+ * — {@link planSqliteTableRebuilds} hoists the rebuild ahead of them for
41
+ * exactly that reason.
42
+ *
43
+ * ## Why the copy carries no CAST
44
+ *
45
+ * The copy is a plain `INSERT INTO new SELECT ... FROM old`; SQLite applies
46
+ * the destination column's *affinity* on insert, which is exactly the
47
+ * conversion a fresh table would have performed (integer `1` becomes real
48
+ * `1.0` in a REAL column). An explicit `CAST` would be strictly worse: casting
49
+ * a non-numeric TEXT value to REAL/INTEGER silently yields `0`, and casting an
50
+ * ISO timestamp string to SQLite's NUMERIC-affinity `DATETIME` silently yields
51
+ * the leading year. Affinity conversion leaves values it cannot convert
52
+ * untouched instead of destroying them.
53
+ *
54
+ * ## When the rebuild refuses
55
+ *
56
+ * With `PRAGMA foreign_keys` enabled — which the SMRT SQLite adapter is by
57
+ * default — `DROP TABLE` performs an implicit `DELETE FROM` that fires
58
+ * `ON DELETE` actions on children. A child with `ON DELETE CASCADE` therefore
59
+ * loses its rows, and `defer_foreign_keys` does not help: it defers
60
+ * constraint *checks*, not FK *actions*. So when any table declares a foreign
61
+ * key onto the rebuild target and enforcement is on, the plan is refused and
62
+ * the change stays a manual intervention. That includes the target's own
63
+ * self-references, because the staging table copies them and so becomes a
64
+ * child of the table being dropped.
65
+ */
66
+ import type { SchemaChange, SQLDataType } from '../schema/types.js';
67
+ import type { DatabaseInterface } from './types.js';
3
68
  /**
4
69
  * Prefix of the reserved staging table a rebuild creates. `_smrt_`-prefixed
5
70
  * names are SMRT system tables, which the differ's dropped-table sweep skips,
@@ -1,7 +1,13 @@
1
+ /**
2
+ * Migration Tracker
3
+ *
4
+ * Manages migration state, tracking which migrations have been applied,
5
+ * and providing idempotent migration application.
6
+ */
1
7
  import { parsePostgresTimeoutMs } from '../postgres-timeouts.js';
2
- import { DatabaseEngine } from '../schema/ddl/types.js';
3
- import { DriftReport, MigrationDefinition, MigrationResult, MigrationStatus, SchemaMigrationRecord } from '../schema/types.js';
4
- import { ApplyMigrationsOptions, MigrationTrackerOptions, RollbackOptions } from './types.js';
8
+ import type { DatabaseEngine } from '../schema/ddl/types.js';
9
+ import type { DriftReport, MigrationDefinition, MigrationResult, MigrationStatus, SchemaMigrationRecord } from '../schema/types.js';
10
+ import type { ApplyMigrationsOptions, MigrationTrackerOptions, RollbackOptions } from './types.js';
5
11
  /**
6
12
  * Extract the index name from a `CREATE [UNIQUE] INDEX …` statement.
7
13
  *
@@ -1,5 +1,10 @@
1
- import { DatabaseInterface, ColumnDefinitionWithName as SqlColumnDefinitionWithName, IndexDefinition as SqlIndexDefinition, TableSchemaInfo as SqlTableSchemaInfo } from '@happyvertical/sql';
2
- import { MigrationResult } from '../schema/types.js';
1
+ /**
2
+ * Migration Types
3
+ *
4
+ * Re-exports migration types from schema and adds migration-specific types.
5
+ */
6
+ import type { DatabaseInterface, ColumnDefinitionWithName as SqlColumnDefinitionWithName, IndexDefinition as SqlIndexDefinition, TableSchemaInfo as SqlTableSchemaInfo } from '@happyvertical/sql';
7
+ import type { MigrationResult } from '../schema/types.js';
3
8
  export type { DriftReport, MigrationDefinition, MigrationResult, MigrationStatus, SchemaChange, SchemaDiff, SchemaMigrationRecord, } from '../schema/types.js';
4
9
  export type { DatabaseInterface, SqlColumnDefinitionWithName, SqlIndexDefinition, SqlTableSchemaInfo, };
5
10
  /**
package/dist/object.d.ts CHANGED
@@ -1,9 +1,10 @@
1
- import { AITextCompletionOptions, AITool } from '@happyvertical/ai';
2
- import { SmrtClassOptions, SmrtClass } from './class';
3
- import { DatabaseErrorClassification } from './db-errors';
4
- import { EvaluateOptions, EvaluationResult } from './decisions';
5
- import { GenerateEmbeddingsOptions } from './embeddings/types';
6
- import { ToolCall, ToolCallResult } from './tools/tool-executor';
1
+ import type { AITextCompletionOptions, AITool } from '@happyvertical/ai';
2
+ import type { SmrtClassOptions } from './class';
3
+ import { SmrtClass } from './class';
4
+ import { type DatabaseErrorClassification } from './db-errors';
5
+ import { type EvaluateOptions, type EvaluationResult } from './decisions';
6
+ import type { GenerateEmbeddingsOptions } from './embeddings/types';
7
+ import { type ToolCall, type ToolCallResult } from './tools/tool-executor';
7
8
  /** Optional optimistic-concurrency guard for persisted-object saves. */
8
9
  export interface SmrtSaveOptions {
9
10
  /**
@@ -1,4 +1,47 @@
1
- import { SmrtObject, SmrtObjectOptions } from './object';
1
+ /**
2
+ * SmrtPolymorphicAssociation — base class for polymorphic association rows.
3
+ *
4
+ * A polymorphic association links an owner row to an arbitrary target
5
+ * SmrtObject identified by a `(metaType, metaId)` pair — `metaType` being the
6
+ * target's qualified class name (e.g. `@happyvertical/smrt-content:Article`)
7
+ * and `metaId` its row id. Pair that with a `role` discriminator and a
8
+ * `sortOrder`, and one join table can reference many different target types
9
+ * without a typed foreign key per type.
10
+ *
11
+ * Subclasses add their own "owner" side and decorate with `@smrt()`:
12
+ *
13
+ * ```typescript
14
+ * @smrt({ conflictColumns: ['asset_id', 'meta_type', 'meta_id', 'role'] })
15
+ * export class AssetAssociation extends SmrtPolymorphicAssociation {
16
+ * @foreignKey('Asset', { required: true })
17
+ * assetId = '';
18
+ * }
19
+ *
20
+ * const target = await association.hydrate(); // resolves metaType + loads metaId
21
+ * ```
22
+ *
23
+ * Convention: `metaId` is intentionally a bare string, NOT a typed
24
+ * `@foreignKey` / `@crossPackageRef` — it is polymorphic, so there is no
25
+ * single target table to point at. `metaType` carries the type information
26
+ * instead, resolved at runtime via `ObjectRegistry`.
27
+ *
28
+ * This is an abstract framework base in the same family as
29
+ * `SmrtHierarchical` and `SmrtJunction`: it has no `@smrt()` decorator and no
30
+ * table of its own. Its columns are merged into each concrete subclass's
31
+ * manifest by the scanner's `FRAMEWORK_BASE_CLASSES` /
32
+ * `FRAMEWORK_ABSTRACT_BASE_NAMES` wiring. Keep those two lists in sync when
33
+ * touching this class.
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * @smrt({ conflictColumns: ['owner_id', 'meta_type', 'meta_id', 'role'] })
38
+ * export class CommentAssociation extends SmrtPolymorphicAssociation {
39
+ * @foreignKey('Comment', { required: true })
40
+ * ownerId = '';
41
+ * }
42
+ * ```
43
+ */
44
+ import { SmrtObject, type SmrtObjectOptions } from './object';
2
45
  /**
3
46
  * Options accepted by `SmrtPolymorphicAssociation` (and its subclasses)
4
47
  * covering the polymorphic right side of the join.
@@ -1,4 +1,4 @@
1
- import { DatabaseInterface } from '@happyvertical/sql';
1
+ import type { DatabaseInterface } from '@happyvertical/sql';
2
2
  /** PostgreSQL ACLs only; this is not application authorization or RLS. */
3
3
  export interface PostgresPermissionContract {
4
4
  schema: string;
@@ -1,4 +1,8 @@
1
- import { SmartObjectManifest } from '../scanner/types';
1
+ /**
2
+ * Pre-build utilities for generating TypeScript declarations
3
+ * Solves virtual module resolution by creating physical .d.ts files
4
+ */
5
+ import type { SmartObjectManifest } from '../scanner/types';
2
6
  export interface PrebuildOptions {
3
7
  /** Path to manifest file or manifest object */
4
8
  manifest: string | SmartObjectManifest;
@@ -1,3 +1,29 @@
1
+ /**
2
+ * Query bounds for list surfaces (#2367).
3
+ *
4
+ * Every generated read surface — REST, SvelteKit routes, the MCP server and the
5
+ * MCP runtime bootstrap — takes `limit`/`offset` straight from untrusted input.
6
+ * Before this module each one parsed them by hand, and each got it wrong in a
7
+ * different way: `Number.parseInt('abc')` produced `LIMIT NaN` (a 500 from the
8
+ * driver, not a 400 from the API), `Number(x) || 50` silently turned `0` into
9
+ * `50`, and none of them capped the value, so `?limit=100000000` was a
10
+ * single-request table scan on every generated endpoint.
11
+ *
12
+ * This is the one parser they all share. It is deliberately strict on the input
13
+ * (a bound is a non-negative integer or it is a client error) and deliberately
14
+ * forgiving on magnitude (an oversized page is clamped, not rejected, so a
15
+ * caller paging with a too-large window still makes progress instead of
16
+ * receiving an error it cannot act on).
17
+ *
18
+ * The bounds themselves are also available to `SmrtCollection.list()` through
19
+ * the `defaultListLimit` / `maxListLimit` collection options. Those are opt-in:
20
+ * `list()` is the framework's own bulk-read primitive and dozens of internal
21
+ * callers (relationship loaders, junction hydration, `listByIds`) legitimately
22
+ * expect every matching row, so a framework-wide implicit default would
23
+ * silently truncate results rather than bound an attack surface. The bound
24
+ * belongs where untrusted input arrives, which is why the generated surfaces
25
+ * apply it unconditionally and direct programmatic callers opt in.
26
+ */
1
27
  import { ValidationError } from './errors';
2
28
  /**
3
29
  * Page size a generated list surface uses when the caller supplies none.
@@ -1,4 +1,13 @@
1
- import { CollectionCacheConfig } from '../collection-cache';
1
+ /**
2
+ * Collection read-cache configuration resolution for the SMRT ObjectRegistry.
3
+ *
4
+ * Resolves the effective `@smrt({ cache })` config for a class, walking the
5
+ * inheritance chain so an STI base class opt-in covers its children while a
6
+ * child can still opt out with `cache: false`.
7
+ *
8
+ * @see https://github.com/happyvertical/smrt/issues/1498
9
+ */
10
+ import type { CollectionCacheConfig } from '../collection-cache';
2
11
  /**
3
12
  * Resolve the effective collection cache config for a class.
4
13
  *
@@ -1,6 +1,14 @@
1
+ /**
2
+ * Class registration module for the SMRT ObjectRegistry.
3
+ *
4
+ * Handles registering classes, collections, and manifest entries.
5
+ *
6
+ * Extracted from registry.ts as part of issue #1006.
7
+ * @see https://github.com/happyvertical/smrt/issues/1006
8
+ */
1
9
  import { SmrtObject } from '../object';
2
- import { SmartObjectDefinition } from '../scanner/types.js';
3
- import { RegisteredClass, RegisteredField, SmartObjectConfig } from './types.js';
10
+ import type { SmartObjectDefinition } from '../scanner/types.js';
11
+ import type { RegisteredClass, RegisteredField, SmartObjectConfig } from './types.js';
4
12
  /**
5
13
  * Shared bundled-context detector. Source files in these output
6
14
  * directories come from a bundler (Vite library mode, webpack, Next.js,
@@ -1,4 +1,4 @@
1
- import { RegisteredClass } from './types';
1
+ import type { RegisteredClass } from './types';
2
2
  export interface CollectionRegistrationLookup {
3
3
  findClass: (name: string) => RegisteredClass | undefined;
4
4
  findClassInPackage?: (packageName: string, className: string) => RegisteredClass | undefined;
@@ -1,4 +1,12 @@
1
- import { ClassEmbeddingConfig, ProjectEmbeddingConfig, ResolvedEmbeddingConfig } from '../embeddings/types';
1
+ /**
2
+ * Embedding configuration management for the SMRT ObjectRegistry.
3
+ *
4
+ * Handles class-level and project-level embedding config resolution.
5
+ *
6
+ * Extracted from registry.ts as part of issue #1006.
7
+ * @see https://github.com/happyvertical/smrt/issues/1006
8
+ */
9
+ import type { ClassEmbeddingConfig, ProjectEmbeddingConfig, ResolvedEmbeddingConfig } from '../embeddings/types';
2
10
  /**
3
11
  * Get embedding configuration for a class.
4
12
  */
@@ -1,6 +1,11 @@
1
- import { SmrtObject } from '../object';
2
- import { MethodDefinition } from '../scanner/types.js';
3
- import { RegisteredField } from './types';
1
+ /**
2
+ * Inheritance resolution module for the SMRT ObjectRegistry.
3
+ *
4
+ * Extracted from registry.ts as part of issue #1006.
5
+ */
6
+ import type { SmrtObject } from '../object';
7
+ import type { MethodDefinition } from '../scanner/types.js';
8
+ import type { RegisteredField } from './types';
4
9
  /**
5
10
  * Runtime field shape merged across an inheritance chain.
6
11
  *
@@ -1,5 +1,5 @@
1
- import { FieldDefinition } from '../scanner/types.js';
2
- import { RegisteredField } from './types';
1
+ import type { FieldDefinition } from '../scanner/types.js';
2
+ import type { RegisteredField } from './types';
3
3
  /**
4
4
  * Manifest-sourced field input handled by the merge helpers.
5
5
  *
@@ -1,5 +1,25 @@
1
- import { QualifiedClassName, SmrtVisibility } from '../scanner/types.js';
2
- import { RegisteredClass, SmrtObjectConstructor } from './types';
1
+ /**
2
+ * Name resolution module for the SMRT ObjectRegistry.
3
+ *
4
+ * Handles class lookup, disambiguation, and qualified name resolution.
5
+ * All functions operate on the shared globalThis state.
6
+ *
7
+ * Release B (#1133): classNameMap is gone — the eagerly-maintained
8
+ * lowercase-simple-name → qualified-key[] index was removed in favor of
9
+ * on-demand iteration over the `classes` Map. Production SMRT apps carry
10
+ * a few hundred classes at most, so the linear scan is negligible and
11
+ * removes an entire class of cache-sync bugs (#584, #847, #951).
12
+ *
13
+ * #3047: hydration resolves names per row, so the scan now runs once per
14
+ * registry generation into a derived (never hand-maintained) index; see
15
+ * `getSimpleNameIndex()` and `registry/generation.ts`.
16
+ *
17
+ * Extracted from registry.ts as part of issue #1006.
18
+ * @see https://github.com/happyvertical/smrt/issues/1006
19
+ * @see https://github.com/happyvertical/smrt/issues/1133
20
+ */
21
+ import type { QualifiedClassName, SmrtVisibility } from '../scanner/types.js';
22
+ import type { RegisteredClass, SmrtObjectConstructor } from './types';
3
23
  /**
4
24
  * Check if a class is already registered (case-insensitive).
5
25
  * Returns the canonical name if found, undefined otherwise. Returns
@@ -1,4 +1,12 @@
1
- import { RelationshipMetadata } from './types';
1
+ /**
2
+ * Relationship graph and dependency resolution module for the SMRT ObjectRegistry.
3
+ *
4
+ * Builds relationship maps and dependency graphs from registered class fields.
5
+ *
6
+ * Extracted from registry.ts as part of issue #1006.
7
+ * @see https://github.com/happyvertical/smrt/issues/1006
8
+ */
9
+ import type { RelationshipMetadata } from './types';
2
10
  /** Canonical target of the field's declaring class, including inherited fields. */
3
11
  export declare function resolveRelationshipTarget(className: string, fieldName: string): string | null | undefined;
4
12
  /**
@@ -1,6 +1,11 @@
1
- import { FieldDefinition } from '../scanner/types.js';
2
- import { DatabaseEngine } from '../schema/ddl/types.js';
3
- import { ColumnDefinition, SchemaDefinition, SQLDataType } from '../schema/types.js';
1
+ /**
2
+ * Schema building logic for the SMRT ObjectRegistry.
3
+ *
4
+ * Extracted from registry.ts as part of issue #1006.
5
+ */
6
+ import type { FieldDefinition } from '../scanner/types.js';
7
+ import type { DatabaseEngine } from '../schema/ddl/types.js';
8
+ import type { ColumnDefinition, SchemaDefinition, SQLDataType } from '../schema/types.js';
4
9
  /**
5
10
  * Get cached schema definition for a registered class
6
11
  *
@@ -1,6 +1,16 @@
1
- import { SmrtCollection } from '../collection';
1
+ /**
2
+ * Shared state accessors for the SMRT ObjectRegistry.
3
+ *
4
+ * All registry sub-modules share state via globalThis to ensure
5
+ * cross-module consistency in monorepo environments.
6
+ *
7
+ * Extracted from registry.ts as part of issue #1006.
8
+ * @see https://github.com/happyvertical/smrt/issues/1006
9
+ * @see https://github.com/happyvertical/smrt/issues/543
10
+ */
11
+ import type { SmrtCollection } from '../collection';
2
12
  import { LRUCache } from '../utils/lru-cache';
3
- import { RegisteredClass, SmrtObjectConstructor } from './types';
13
+ import type { RegisteredClass, SmrtObjectConstructor } from './types';
4
14
  declare global {
5
15
  var __smrtRegistryClasses: Map<string, RegisteredClass> | undefined;
6
16
  var __smrtRegistryCollections: Map<string, typeof SmrtCollection> | undefined;
@@ -1,10 +1,18 @@
1
- import { CapabilityEffect, DomainKnowledgeConfig } from '@happyvertical/smrt-types';
2
- import { SmrtCollection } from '../collection';
3
- import { CollectionCacheConfig } from '../collection-cache';
4
- import { FieldOptions } from '../decorators/index.js';
5
- import { SmrtObject } from '../object';
6
- import { FieldDefinition, FieldMeta, MethodDefinition, QualifiedClassName, SmartObjectManifest, SmrtVisibility, ValidationRule } from '../scanner/types.js';
7
- import { DeclaredIndexDefinition, SchemaDefinition } from '../schema/types.js';
1
+ /**
2
+ * Type definitions for the SMRT ObjectRegistry.
3
+ *
4
+ * Extracted from registry.ts as part of issue #1006
5
+ * (Split ObjectRegistry into focused modules).
6
+ *
7
+ * @see https://github.com/happyvertical/smrt/issues/1006
8
+ */
9
+ import type { CapabilityEffect, DomainKnowledgeConfig } from '@happyvertical/smrt-types';
10
+ import type { SmrtCollection } from '../collection';
11
+ import type { CollectionCacheConfig } from '../collection-cache';
12
+ import type { FieldOptions } from '../decorators/index.js';
13
+ import type { SmrtObject } from '../object';
14
+ import type { FieldDefinition, FieldMeta, MethodDefinition, QualifiedClassName, SmartObjectManifest, SmrtVisibility, ValidationRule } from '../scanner/types.js';
15
+ import type { DeclaredIndexDefinition, SchemaDefinition } from '../schema/types.js';
8
16
  /**
9
17
  * Type for any constructor function that extends SmrtObject.
10
18
  * Used for WeakMap keys where we need to accept any subclass constructor.
@@ -1,5 +1,13 @@
1
- import { FieldDefinition } from '../scanner/types.js';
2
- import { ValidatorFunction } from './types';
1
+ /**
2
+ * Validator module for the SMRT ObjectRegistry.
3
+ *
4
+ * Compiles validation functions from field definitions for runtime use.
5
+ *
6
+ * Extracted from registry.ts as part of issue #1006.
7
+ * @see https://github.com/happyvertical/smrt/issues/1006
8
+ */
9
+ import type { FieldDefinition } from '../scanner/types.js';
10
+ import type { ValidatorFunction } from './types';
3
11
  export declare function isBatchSafeValidator(validator: ValidatorFunction): boolean;
4
12
  /**
5
13
  * Compile validation functions from field definitions.