@happyvertical/smrt-core 0.57.29 → 0.57.31
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/AGENTS.md +1 -0
- package/agents/build-knowledge.md +8 -0
- package/agents/deployment-phases.md +71 -0
- package/agents/generators.md +26 -0
- package/dist/consumer-plugin/index.d.ts.map +1 -1
- package/dist/consumer-plugin/index.js +9 -3
- package/dist/consumer-plugin/index.js.map +1 -1
- package/dist/manifest/static-manifest.js +1 -1
- package/dist/manifest/static-manifest.js.map +1 -1
- package/dist/manifest/store.js +1 -1
- package/dist/manifest.json +1 -1
- package/dist/migrations/deployment-phase-tracker.d.ts +57 -0
- package/dist/migrations/deployment-phase-tracker.d.ts.map +1 -0
- package/dist/migrations/deployment-phase-tracker.js +179 -0
- package/dist/migrations/deployment-phase-tracker.js.map +1 -0
- package/dist/migrations/index.d.ts +1 -0
- package/dist/migrations/index.d.ts.map +1 -1
- package/dist/migrations/index.js +2 -1
- package/dist/migrations.js +2 -1
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +3 -1
- package/dist/registry.js.map +1 -1
- package/dist/smrt-knowledge.json +15 -9
- package/dist/vite-plugin/sveltekit-generator.d.ts.map +1 -1
- package/dist/vite-plugin/sveltekit-generator.js +21 -12
- package/dist/vite-plugin/sveltekit-generator.js.map +1 -1
- package/package.json +10 -10
package/AGENTS.md
CHANGED
|
@@ -15,6 +15,7 @@ and repository rules.
|
|
|
15
15
|
| `src/data-query.ts` | Transport-neutral bounded query normalization | [agents/data-query.md](agents/data-query.md) |
|
|
16
16
|
| `src/schema/`, `src/migrations/`, `src/cascade.ts`, `src/system/` | DDL parity, indexes, migrations, delete integrity, retention | [agents/schema-paths.md](agents/schema-paths.md) |
|
|
17
17
|
| `src/postgres-permissions.ts` | Explicit PostgreSQL ACL plans and atomic reconciliation | [deployment permission contract](../../docs/content/postgres-permissions.md) |
|
|
18
|
+
| `src/migrations/deployment-phase-tracker.ts` | Permanent checksummed PostgreSQL deployment steps, atomic markers and explicit external-effect reconciliation | [agents/deployment-phases.md](agents/deployment-phases.md) |
|
|
18
19
|
| `src/change-feed.ts` | Durable changes, cursors, table versions, retention | [agents/change-feed.md](agents/change-feed.md) |
|
|
19
20
|
| `src/change-feed-authz.ts` | Consumer table/row change-feed authorization hooks (#3020) | [agents/change-feed.md](agents/change-feed.md) |
|
|
20
21
|
| `src/change-signals.ts` | Signal bus, replica fan-out, SSE | [agents/change-signals.md](agents/change-signals.md) |
|
|
@@ -121,6 +121,14 @@ that declares `svelte` anyway only loses an optional context import.
|
|
|
121
121
|
Transitive-only object modules are loaded through `importSmrtDependency()`
|
|
122
122
|
from their provider's context, which needs no root import.
|
|
123
123
|
|
|
124
|
+
Selective SSR compilation compares a JavaScript barrel's `svelte` export target
|
|
125
|
+
against the package instance visible from its actual importer. pnpm may install
|
|
126
|
+
the same version in multiple peer contexts; the app-root package directory is
|
|
127
|
+
not the identity of a transitive import. Read that importer's installed export
|
|
128
|
+
map and root together, preserving exact target matching. Plain server entries
|
|
129
|
+
remain external; do not fix peer-context resolution by deduplicating app
|
|
130
|
+
packages or bundling every server export (#4318).
|
|
131
|
+
|
|
124
132
|
Not covered by contract: a package whose root is a Svelte entry AND whose
|
|
125
133
|
`@smrt()` objects are exported only from that root. The object loop must then
|
|
126
134
|
import the root (it is the only module exporting the constructors) — statically
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Durable deployment data steps
|
|
2
|
+
|
|
3
|
+
`DeploymentPhaseTracker`, exported from `@happyvertical/smrt-core/migrations`,
|
|
4
|
+
is a PostgreSQL-only deployment data-step API. SQL schema steps continue to use
|
|
5
|
+
`MigrationTracker`, including its checksums and concurrent-index recovery.
|
|
6
|
+
|
|
7
|
+
A permanent `_smrt_deployment_steps` ledger keys each step by `application`,
|
|
8
|
+
`environment`, and stable `stepId`. Reusing an ID with a different checksum or
|
|
9
|
+
execution mode fails before its work or inspection executes. A release identifier
|
|
10
|
+
alone is not a stable step ID: otherwise later releases replay old data changes.
|
|
11
|
+
There is no retention. Preserve this table when restoring data; deleting markers
|
|
12
|
+
permits replay. Checkpoints must never contain secrets. `MAX_DEPLOYMENT_CHECKPOINT_BYTES` limits
|
|
13
|
+
serialized checkpoint JSON to 16 KiB measured in UTF-8 bytes, including quotes
|
|
14
|
+
and JSON syntax. Oversized or unserializable values fail with
|
|
15
|
+
`INVALID_CHECKPOINT` before their ledger query; the prior durable checkpoint is
|
|
16
|
+
preserved. Values follow `JSON.stringify` conventions: undefined/null checkpoints
|
|
17
|
+
normalize to null, nonfinite numbers become null, object properties containing
|
|
18
|
+
undefined/functions/symbols are omitted, and those array elements become null.
|
|
19
|
+
Circular references, BigInt, and top-level functions/symbols are rejected.
|
|
20
|
+
A checkpoint rejection does not undo prior external effects: reconciliation
|
|
21
|
+
still determines whether they completed or may safely resume.
|
|
22
|
+
|
|
23
|
+
Every execution requires `checkSafety(connection)`: a read-only callback that
|
|
24
|
+
throws unless runtime/static schema agreement and writer quiescence have been
|
|
25
|
+
proved. It runs after acquiring the scope lock and before any ledger DDL or data
|
|
26
|
+
write, including a replay. The caller owns platform fencing and complete writer
|
|
27
|
+
inventory; an advisory lock excludes cooperating deployment runners, not runtime
|
|
28
|
+
writers. Guards must not open transactions or change session/lock state.
|
|
29
|
+
|
|
30
|
+
The adapter must expose public `acquireSession()`. A session advisory lock
|
|
31
|
+
serializes every step in the same application/environment; the same pinned
|
|
32
|
+
session executes data writes and markers. Lock acquisition times out after
|
|
33
|
+
`lockTimeoutMs` (default 30 seconds). Other adapters fail closed. DDL provision
|
|
34
|
+
runs outside the data transaction under a separate initialization lock. The
|
|
35
|
+
migration role needs schema CREATE and ledger read/write permissions.
|
|
36
|
+
|
|
37
|
+
`runTransactionalStep(options, async tx => { ... })` exposes a query-only handle
|
|
38
|
+
on that pinned session. Use **only that handle** for all transactional mutations.
|
|
39
|
+
Data and the completed marker commit together. A thrown callback rolls both back;
|
|
40
|
+
a lost COMMIT response is never retried internally. On retry, the committed marker
|
|
41
|
+
skips work, or the absent marker permits a fresh transaction. Do not issue
|
|
42
|
+
transaction control, DDL requiring autocommit, session configuration or advisory
|
|
43
|
+
lock changes inside callbacks. Work outside this handle is not made atomic.
|
|
44
|
+
|
|
45
|
+
`runReconciledStep({ ...options, inspect, apply })` commits a running marker before
|
|
46
|
+
calling either callback. `inspect(context)` must independently classify actual
|
|
47
|
+
effects as `complete`, `safe-to-resume`, or `needs-repair`. It runs on fresh and
|
|
48
|
+
interrupted attempts. Only `safe-to-resume` permits `apply(context)`, and another
|
|
49
|
+
inspection must prove complete afterward. `saveCheckpoint(json)` persists a
|
|
50
|
+
running checkpoint before external effects; `context.checkpoint` exposes the
|
|
51
|
+
latest value. Each effect must tolerate the interval between performing it and
|
|
52
|
+
saving its checkpoint. No blind shell-command replay is provided.
|
|
53
|
+
|
|
54
|
+
A failure records needs-repair if the session survives; process/connection death
|
|
55
|
+
can leave running. Both are unresolved and require inspection on the next attempt.
|
|
56
|
+
`getStepStatus(key)` is read-only and reports the durable status without guessing
|
|
57
|
+
whether a running owner is alive. A reconciler may prove a needs-repair attempt
|
|
58
|
+
safe to resume after an operator repairs the underlying problem. A callback that
|
|
59
|
+
cannot determine safety must return needs-repair and refuse further mutation.
|
|
60
|
+
|
|
61
|
+
External effects cannot be atomically fenced by a PostgreSQL connection:
|
|
62
|
+
`assertActive()` checks the pinned session, but it cannot stop an already-running
|
|
63
|
+
shell command or fence an external service after connection loss. Applications
|
|
64
|
+
must supply service-specific fencing/idempotency and truthful inspection, or
|
|
65
|
+
require manual repair. This API makes no exactly-once claim for external effects.
|
|
66
|
+
|
|
67
|
+
Focused validation: `pnpm --filter @happyvertical/smrt-core exec vitest run
|
|
68
|
+
src/migrations/__tests__/deployment-phase-tracker-postgres.optional.test.ts` with
|
|
69
|
+
`SMRT_TEST_POSTGRES_URL` pointing to an isolated PostgreSQL database. Tests use
|
|
70
|
+
separate pools to exercise serialization, atomic marker/data rollback and commit,
|
|
71
|
+
checksum refusal, and ambiguous nontransactional recovery.
|
package/agents/generators.md
CHANGED
|
@@ -457,3 +457,29 @@ model-level validation, and regenerate RLS policies when adopting a changed
|
|
|
457
457
|
binding.
|
|
458
458
|
|
|
459
459
|
Custom actions retain the `{ action, result }` response envelope.
|
|
460
|
+
|
|
461
|
+
## Collection-hosted REST factory identity (#4320)
|
|
462
|
+
|
|
463
|
+
Generated collection custom-action handlers resolve their executable collection
|
|
464
|
+
using the declaring resource's exact qualified registration key. Keep that
|
|
465
|
+
factory key separate from the item model's qualified type/policy metadata:
|
|
466
|
+
item collection slugs still govern permissions, and ordinary model routes keep
|
|
467
|
+
their own factory lookup. A resource in another package must neither rebuild
|
|
468
|
+
an item identity under its package nor steal the item's existing package when
|
|
469
|
+
its collection decorator merges configuration. Registration and generated
|
|
470
|
+
factory selection share one identity resolver; never install global aliases to
|
|
471
|
+
repair an inferred or bundled class name.
|
|
472
|
+
|
|
473
|
+
Every collection hosting a generated REST action receives its exact constructor
|
|
474
|
+
binding even with `cli: false` or omitted CLI configuration. This runtime-only
|
|
475
|
+
binding does not add discovery metadata: named HTTP CLI resources keep their
|
|
476
|
+
existing explicit-include eligibility. Constructor-only qualified receivers keep
|
|
477
|
+
their own collection-cache identity while resolving backing item metadata, so
|
|
478
|
+
ordinary model factories cannot reuse a different resource receiver. Neither
|
|
479
|
+
CLI nor MCP discovery gains a resource or default CRUD surface from this binding.
|
|
480
|
+
|
|
481
|
+
When consumer registration owns external packages (`smrtDependencies`), its
|
|
482
|
+
`.smrt/register.js` binds external REST action receivers using the resolved
|
|
483
|
+
canonical/provider-context export. The SvelteKit registration module continues
|
|
484
|
+
to delegate external imports there; external bindings also add no discovery
|
|
485
|
+
metadata and do not depend on CLI inclusion.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/consumer-plugin/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAa,MAAM,EAAE,MAAM,MAAM,CAAC;AAC9C,OAAO,EAEL,KAAK,6BAA6B,EACnC,MAAM,2BAA2B,CAAC;AAYnC,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/consumer-plugin/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAa,MAAM,EAAE,MAAM,MAAM,CAAC;AAC9C,OAAO,EAEL,KAAK,6BAA6B,EACnC,MAAM,2BAA2B,CAAC;AAYnC,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,uCAAuC,CAAC;AAqB/C,OAAO,EACL,kCAAkC,EAClC,KAAK,sCAAsC,EAC3C,KAAK,8BAA8B,EACnC,KAAK,6BAA6B,EAClC,KAAK,0BAA0B,EAC/B,+BAA+B,EAC/B,4BAA4B,GAC7B,MAAM,2BAA2B,CAAC;AAiJnC;;;GAGG;AACH,UAAU,oBAAoB;IAC5B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,sBAAsB,CACpC,WAAW,EAAE,oBAAoB,GAAG,SAAS,GAC5C,OAAO,CAcT;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,4BAA4B,CAC1C,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,oBAAoB,GAAG,SAAS,GAC5C,MAAM,GAAG,SAAS,CAEpB;AAED;;;;GAIG;AACH,MAAM,WAAW,4BACf,SAAQ,OAAO,CACb,IAAI,CACF,gBAAgB,EACd,WAAW,GACX,YAAY,GACZ,YAAY,GACZ,gBAAgB,GAChB,aAAa,GACb,cAAc,GACd,aAAa,GACb,gBAAgB,CACnB,CACF;IACD,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,mBAAmB;IAClC,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,uCAAuC;IACvC,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,6BAA6B,CAAC;IACnD;;;;OAIG;IACH,SAAS,CAAC,EAAE,OAAO,GAAG,4BAA4B,CAAC;IACnD;;;;;OAKG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,oDAAoD;IACpD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4BAA4B;IAC5B,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAmXD;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,GAAE,mBAAwB,GAAG,MAAM,CA2lBtE"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import "../scanner/types.js";
|
|
2
2
|
import { canonicalSvelteKitPath } from "../vite-plugin/sveltekit-path.js";
|
|
3
|
-
import { clearGeneratedSvelteKitRouteFiles, reconcileSvelteKitRouteGitignore } from "../vite-plugin/sveltekit-generator.js";
|
|
3
|
+
import { clearGeneratedSvelteKitRouteFiles, reconcileSvelteKitRouteGitignore, resolveApiActionSet } from "../vite-plugin/sveltekit-generator.js";
|
|
4
4
|
import { generateWebModule, isCollectionManifestClass, resolveCollectionItemObject } from "../vite-plugin/web-collections.js";
|
|
5
5
|
import { publishArtifactFiles } from "./artifact-publication.js";
|
|
6
6
|
import { resolveFileKnowledgeConfig } from "../knowledge-config.js";
|
|
@@ -523,7 +523,10 @@ function smrtConsumer(options = {}) {
|
|
|
523
523
|
skipSelf: true
|
|
524
524
|
});
|
|
525
525
|
const compile = resolved?.id.endsWith(".svelte") || resolved?.id.endsWith(".css");
|
|
526
|
-
const
|
|
526
|
+
const importerPath = importer?.split("?")[0];
|
|
527
|
+
const packageJsonPath = importerPath && path$1.isAbsolute(importerPath) ? findInstalledPackageJson(packageName, path$1.dirname(importerPath)) : void 0;
|
|
528
|
+
const packageJson = packageJsonPath ? readInstalledPackageJson(packageJsonPath) : selectivePackage.packageJson;
|
|
529
|
+
const compileSvelteBarrel = packageJson && resolvesToSvelteCondition(packageName, packageJson, packageJsonPath ? path$1.dirname(packageJsonPath) : selectivePackage.packageRoot, id, resolved?.id);
|
|
527
530
|
if (!compile && !compileSvelteBarrel) return {
|
|
528
531
|
id,
|
|
529
532
|
external: true
|
|
@@ -953,7 +956,10 @@ async function generateRegistrationFile(manifest, projectRoot) {
|
|
|
953
956
|
itemBinding: exportBinding
|
|
954
957
|
});
|
|
955
958
|
importedEntryCount++;
|
|
956
|
-
if (isCollectionClass(def))
|
|
959
|
+
if (isCollectionClass(def)) {
|
|
960
|
+
if (resolveApiActionSet(def, manifest).size > 0) registrations.push(`if (${exportBinding}) ObjectRegistry.registerCollection(${JSON.stringify(qualifiedName)}, ${exportBinding});`);
|
|
961
|
+
continue;
|
|
962
|
+
}
|
|
957
963
|
const logicalName = def.className || exportName;
|
|
958
964
|
registrationManifests[objectName] = {
|
|
959
965
|
...manifest,
|