@happyvertical/smrt-core 0.40.63 → 0.40.64
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 +13 -0
- package/README.md +38 -0
- package/dist/__typechecks__/collection-read-plan.d.ts +50 -0
- package/dist/__typechecks__/collection-read-plan.d.ts.map +1 -0
- package/dist/collection-read-plan.d.ts +77 -0
- package/dist/collection-read-plan.d.ts.map +1 -0
- package/dist/collection-read-plan.js +55 -0
- package/dist/collection-read-plan.js.map +1 -0
- package/dist/consumer-plugin/index.d.ts.map +1 -1
- package/dist/consumer-plugin/index.js +44 -5
- package/dist/consumer-plugin/index.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -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/object.d.ts.map +1 -1
- package/dist/object.js +1 -1
- package/dist/object.js.map +1 -1
- package/dist/registry/class-registration.d.ts.map +1 -1
- package/dist/registry/class-registration.js +53 -3
- package/dist/registry/class-registration.js.map +1 -1
- package/dist/registry/types.d.ts +7 -0
- package/dist/registry/types.d.ts.map +1 -1
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +5 -4
- package/dist/registry.js.map +1 -1
- package/dist/smrt-knowledge.json +5 -5
- package/dist/vite-plugin/sveltekit-generator.d.ts.map +1 -1
- package/dist/vite-plugin/sveltekit-generator.js +92 -26
- package/dist/vite-plugin/sveltekit-generator.js.map +1 -1
- package/package.json +5 -5
package/AGENTS.md
CHANGED
|
@@ -76,6 +76,18 @@ operator against a database to keep the two in step.
|
|
|
76
76
|
|
|
77
77
|
STI child collections auto-filter by `_meta_type`.
|
|
78
78
|
|
|
79
|
+
## Bounded Collection Read Plans
|
|
80
|
+
|
|
81
|
+
Use `executeCollectionReadPlan()` when one operation needs several independent
|
|
82
|
+
collections. It bounds top-level `collection.list()` concurrency while keeping
|
|
83
|
+
all reads on the normal registry/collection path. Callers must choose an
|
|
84
|
+
explicit positive `maxConcurrency` and pass their normal shared
|
|
85
|
+
`collectionOptions` when database or tenant context matters.
|
|
86
|
+
|
|
87
|
+
The executor deliberately does not compose SQL, cache the plan, or change pool
|
|
88
|
+
defaults. On failure it stops starting queued entries, drains operations already
|
|
89
|
+
in flight, and rethrows the first error.
|
|
90
|
+
|
|
79
91
|
## Object Memory & Semantic Search
|
|
80
92
|
|
|
81
93
|
Two persistence primitives every `SmrtObject`/`SmrtCollection` inherits — load-bearing for learning agents, usable by any object. Full guide: `docs/content/core.md` → "Context Memory System".
|
|
@@ -186,3 +198,4 @@ emitDecoratorMetadata: true`.
|
|
|
186
198
|
must abort before adapting partial scan results. A syntax error or unresolved
|
|
187
199
|
`@smrt()` config spread cannot be allowed to emit a default-open manifest.
|
|
188
200
|
- **Vite plugin loads scanner from `dist/` first**: `src/vite-plugin/import-build-aware.ts` prefers `dist/` when it exists on disk; it only falls back to `src/` on fresh clones. So if you edit `src/scanner/*.ts` or `src/schema/generator.ts` and want those edits reflected in consumer manifest generation, you must rebuild (`pnpm build` or have `pnpm dev` / `pnpm build:watch` running in core). This is intentional — sniffing `.ts` vs `.js` via `import.meta.url` was non-deterministic under tsx and broke 12–13 publishes (#1139).
|
|
201
|
+
- **Bundled registry ownership**: flattened production bundles can rewrite constructor names and make decorator-time stack inference attribute provider code to the consumer. Generated registration repairs identity only from the exact imported constructor plus an explicit package and isolated one-object manifest; never infer ownership from output paths, simple names, or table names. Distinct packages may export the same simple name under qualified keys. The production-consumer gate lives in `packages/bundle-gate/src/__tests__/registry-identity.spec.ts` (#2308).
|
package/README.md
CHANGED
|
@@ -67,6 +67,44 @@ const results = await products.list({
|
|
|
67
67
|
|
|
68
68
|
```
|
|
69
69
|
|
|
70
|
+
### Bounded multi-collection reads
|
|
71
|
+
|
|
72
|
+
When one request needs several independent collections, use a keyed read plan
|
|
73
|
+
instead of an unbounded `Promise.all`. Every entry still uses the normal
|
|
74
|
+
collection `list()` path, but only the requested number of operations run at
|
|
75
|
+
once:
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
import {
|
|
79
|
+
executeCollectionReadPlan,
|
|
80
|
+
type SmrtCollectionReadPlanEntry,
|
|
81
|
+
} from '@happyvertical/smrt-core';
|
|
82
|
+
|
|
83
|
+
const categories: SmrtCollectionReadPlanEntry<Category> = {
|
|
84
|
+
className: 'Category',
|
|
85
|
+
options: { orderBy: 'name ASC' },
|
|
86
|
+
};
|
|
87
|
+
const products: SmrtCollectionReadPlanEntry<Product> = {
|
|
88
|
+
className: 'Product',
|
|
89
|
+
options: { where: { isPublished: true }, orderBy: 'name ASC' },
|
|
90
|
+
};
|
|
91
|
+
const records = await executeCollectionReadPlan(
|
|
92
|
+
{
|
|
93
|
+
categories,
|
|
94
|
+
products,
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
collectionOptions: { db: 'file:products.db' },
|
|
98
|
+
maxConcurrency: 2,
|
|
99
|
+
},
|
|
100
|
+
);
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
`maxConcurrency` is required and must be a positive integer. If an entry
|
|
104
|
+
fails, the executor starts no further queued entries, waits for already-running
|
|
105
|
+
entries to settle, and rethrows the first error. Read plans do not compose SQL,
|
|
106
|
+
cache whole-plan results, or change database pool defaults.
|
|
107
|
+
|
|
70
108
|
### Generate metadata and migrate
|
|
71
109
|
|
|
72
110
|
Configure Vite 8's Oxc decorator transform and point `smrtPlugin()` at the
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { SmrtCollectionReadPlan, SmrtCollectionReadPlanEntry, SmrtCollectionReadPlanResult } from '../collection-read-plan';
|
|
2
|
+
import { SmrtObject } from '../object';
|
|
3
|
+
type Equal<Left, Right> = (<Value>() => Value extends Left ? 1 : 2) extends <Value>() => Value extends Right ? 1 : 2 ? true : false;
|
|
4
|
+
type Expect<Value extends true> = Value;
|
|
5
|
+
type ReadPlanTypeProbe = SmrtObject & {
|
|
6
|
+
name: string;
|
|
7
|
+
};
|
|
8
|
+
declare const plain: SmrtCollectionReadPlanEntry<ReadPlanTypeProbe>;
|
|
9
|
+
declare const projected: SmrtCollectionReadPlanEntry<ReadPlanTypeProbe, {
|
|
10
|
+
select: readonly ['id', 'name'];
|
|
11
|
+
}>;
|
|
12
|
+
type Result = SmrtCollectionReadPlanResult<{
|
|
13
|
+
plain: typeof plain;
|
|
14
|
+
projected: typeof projected;
|
|
15
|
+
}>;
|
|
16
|
+
type PlainResultIsTyped = Expect<Equal<Result['plain'], ReadPlanTypeProbe[]>>;
|
|
17
|
+
type ProjectedResultIsTyped = Expect<Equal<Result['projected'], {
|
|
18
|
+
id: string | null | undefined;
|
|
19
|
+
name: string;
|
|
20
|
+
}[]>>;
|
|
21
|
+
type InvalidOptionsAreRejected = Expect<Equal<{
|
|
22
|
+
limit: string;
|
|
23
|
+
} extends NonNullable<SmrtCollectionReadPlan[string]['options']> ? true : false, false>>;
|
|
24
|
+
type ProjectionIncludeIsRejected = Expect<Equal<{
|
|
25
|
+
select: readonly ['id'];
|
|
26
|
+
include: string[];
|
|
27
|
+
} extends NonNullable<SmrtCollectionReadPlan[string]['options']> ? true : false, false>>;
|
|
28
|
+
type MixedOptions = {
|
|
29
|
+
limit: number;
|
|
30
|
+
select?: undefined;
|
|
31
|
+
} | {
|
|
32
|
+
select: readonly ['id'];
|
|
33
|
+
include?: never;
|
|
34
|
+
};
|
|
35
|
+
type MixedEntry = SmrtCollectionReadPlanEntry<ReadPlanTypeProbe, MixedOptions>;
|
|
36
|
+
type MixedResult = SmrtCollectionReadPlanResult<{
|
|
37
|
+
mixed: MixedEntry;
|
|
38
|
+
}>;
|
|
39
|
+
type MixedResultIsSound = Expect<Equal<MixedResult['mixed'], ReadPlanTypeProbe[] | {
|
|
40
|
+
id: string | null | undefined;
|
|
41
|
+
}[]>>;
|
|
42
|
+
export type CollectionReadPlanTypeAssertions = [
|
|
43
|
+
PlainResultIsTyped,
|
|
44
|
+
ProjectedResultIsTyped,
|
|
45
|
+
InvalidOptionsAreRejected,
|
|
46
|
+
ProjectionIncludeIsRejected,
|
|
47
|
+
MixedResultIsSound
|
|
48
|
+
];
|
|
49
|
+
export {};
|
|
50
|
+
//# sourceMappingURL=collection-read-plan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collection-read-plan.d.ts","sourceRoot":"","sources":["../../src/__typechecks__/collection-read-plan.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,sBAAsB,EAC3B,KAAK,2BAA2B,EAChC,KAAK,4BAA4B,EAClC,MAAM,yBAAyB,CAAC;AACjC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAE5C,KAAK,KAAK,CAAC,IAAI,EAAE,KAAK,IACpB,CAAC,CAAC,KAAK,OAAO,KAAK,SAAS,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,SAAS,CAChD,KAAK,OACA,KAAK,SAAS,KAAK,GAAG,CAAC,GAAG,CAAC,GAC9B,IAAI,GACJ,KAAK,CAAC;AACZ,KAAK,MAAM,CAAC,KAAK,SAAS,IAAI,IAAI,KAAK,CAAC;AAExC,KAAK,iBAAiB,GAAG,UAAU,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvD,QAAA,MAAM,KAAK,EAAE,2BAA2B,CAAC,iBAAiB,CAEzD,CAAC;AACF,QAAA,MAAM,SAAS,EAAE,2BAA2B,CAC1C,iBAAiB,EACjB;IAAE,MAAM,EAAE,SAAS,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;CAAE,CAIpC,CAAC;AAEF,KAAK,MAAM,GAAG,4BAA4B,CAAC;IACzC,KAAK,EAAE,OAAO,KAAK,CAAC;IACpB,SAAS,EAAE,OAAO,SAAS,CAAC;CAC7B,CAAC,CAAC;AACH,KAAK,kBAAkB,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,iBAAiB,EAAE,CAAC,CAAC,CAAC;AAC9E,KAAK,sBAAsB,GAAG,MAAM,CAClC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE;IAAE,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,CAC9E,CAAC;AACF,KAAK,yBAAyB,GAAG,MAAM,CACrC,KAAK,CACH;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,SAAS,WAAW,CACnC,sBAAsB,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAC1C,GACG,IAAI,GACJ,KAAK,EACT,KAAK,CACN,CACF,CAAC;AACF,KAAK,2BAA2B,GAAG,MAAM,CACvC,KAAK,CACH;IACE,MAAM,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;IACxB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,SAAS,WAAW,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,GAC5D,IAAI,GACJ,KAAK,EACT,KAAK,CACN,CACF,CAAC;AAEF,KAAK,YAAY,GACb;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,SAAS,CAAA;CAAE,GACrC;IAAE,MAAM,EAAE,SAAS,CAAC,IAAI,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,KAAK,CAAA;CAAE,CAAC;AACjD,KAAK,UAAU,GAAG,2BAA2B,CAAC,iBAAiB,EAAE,YAAY,CAAC,CAAC;AAK/E,KAAK,WAAW,GAAG,4BAA4B,CAAC;IAAE,KAAK,EAAE,UAAU,CAAA;CAAE,CAAC,CAAC;AACvE,KAAK,kBAAkB,GAAG,MAAM,CAC9B,KAAK,CACH,WAAW,CAAC,OAAO,CAAC,EACpB,iBAAiB,EAAE,GAAG;IAAE,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;CAAE,EAAE,CAC1D,CACF,CAAC;AAiCF,MAAM,MAAM,gCAAgC,GAAG;IAC7C,kBAAkB;IAClB,sBAAsB;IACtB,yBAAyB;IACzB,2BAA2B;IAC3B,kBAAkB;CACnB,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { SmrtClassOptions } from './class';
|
|
2
|
+
import { SmrtListOptions, SmrtSelectedRow, SmrtSelectField } from './collection';
|
|
3
|
+
import { SmrtObject } from './object';
|
|
4
|
+
type DynamicSmrtObject = SmrtObject & Record<string, unknown>;
|
|
5
|
+
type SmrtHydratedCollectionReadOptions<ModelType extends SmrtObject> = Omit<SmrtListOptions<ModelType>, 'select'> & {
|
|
6
|
+
select?: undefined;
|
|
7
|
+
};
|
|
8
|
+
type SmrtProjectedCollectionReadOptions<ModelType extends SmrtObject> = Omit<SmrtListOptions<ModelType>, 'select' | 'include'> & {
|
|
9
|
+
select: readonly SmrtSelectField<ModelType>[];
|
|
10
|
+
include?: never;
|
|
11
|
+
};
|
|
12
|
+
type SmrtCollectionReadOptions<ModelType extends SmrtObject> = SmrtHydratedCollectionReadOptions<ModelType> | SmrtProjectedCollectionReadOptions<ModelType>;
|
|
13
|
+
type DynamicSmrtListOptions = SmrtCollectionReadOptions<DynamicSmrtObject>;
|
|
14
|
+
declare const smrtCollectionReadPlanModel: unique symbol;
|
|
15
|
+
type SmrtCollectionReadPlanEntryOptions<ModelType extends SmrtObject, ListOptions extends SmrtCollectionReadOptions<ModelType> | undefined> = ListOptions extends SmrtProjectedCollectionReadOptions<ModelType> ? {
|
|
16
|
+
/** Projection options forwarded unchanged to `SmrtCollection.list()`. */
|
|
17
|
+
options: ListOptions;
|
|
18
|
+
} : {
|
|
19
|
+
/** Standard hydrated-list options forwarded unchanged to `SmrtCollection.list()`. */
|
|
20
|
+
options?: ListOptions;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* One independent collection read in a bounded read plan.
|
|
24
|
+
*
|
|
25
|
+
* `ModelType` is optional for dynamic registries. Consumers that know the
|
|
26
|
+
* model type can annotate an entry to retain model/projection result typing.
|
|
27
|
+
*/
|
|
28
|
+
export type SmrtCollectionReadPlanEntry<ModelType extends SmrtObject = SmrtObject, ListOptions extends SmrtCollectionReadOptions<ModelType> | undefined = SmrtHydratedCollectionReadOptions<ModelType>> = {
|
|
29
|
+
/** Registered SMRT object or collection name. */
|
|
30
|
+
className: string;
|
|
31
|
+
/** @internal Retains the model type for keyed result inference. */
|
|
32
|
+
readonly [smrtCollectionReadPlanModel]?: ModelType;
|
|
33
|
+
} & SmrtCollectionReadPlanEntryOptions<ModelType, ListOptions>;
|
|
34
|
+
/** A keyed group of independent collection reads. */
|
|
35
|
+
export type SmrtCollectionReadPlan = Record<string, {
|
|
36
|
+
className: string;
|
|
37
|
+
options?: DynamicSmrtListOptions;
|
|
38
|
+
}>;
|
|
39
|
+
type SmrtCollectionReadPlanEntryModel<Entry> = Entry extends {
|
|
40
|
+
readonly [smrtCollectionReadPlanModel]?: infer ModelType;
|
|
41
|
+
} ? ModelType extends SmrtObject ? ModelType : SmrtObject : SmrtObject;
|
|
42
|
+
type SmrtCollectionReadPlanEntryResult<Entry> = Entry extends {
|
|
43
|
+
options: {
|
|
44
|
+
select: infer Select;
|
|
45
|
+
};
|
|
46
|
+
} ? Select extends readonly SmrtSelectField<SmrtCollectionReadPlanEntryModel<Entry>>[] ? SmrtSelectedRow<SmrtCollectionReadPlanEntryModel<Entry>, Select>[] : never : SmrtCollectionReadPlanEntryModel<Entry>[];
|
|
47
|
+
/** Results retain the exact keys declared by the input plan. */
|
|
48
|
+
export type SmrtCollectionReadPlanResult<Plan extends SmrtCollectionReadPlan> = {
|
|
49
|
+
[Key in keyof Plan]: SmrtCollectionReadPlanEntryResult<Plan[Key]>;
|
|
50
|
+
};
|
|
51
|
+
export interface ExecuteCollectionReadPlanOptions {
|
|
52
|
+
/**
|
|
53
|
+
* Maximum number of top-level `collection.list()` operations in flight.
|
|
54
|
+
* Must be a positive integer and is intentionally required so callers make
|
|
55
|
+
* workload policy explicit.
|
|
56
|
+
*/
|
|
57
|
+
maxConcurrency: number;
|
|
58
|
+
/** Normal options used to resolve every collection in the plan. */
|
|
59
|
+
collectionOptions?: SmrtClassOptions;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Execute independent collection reads without unbounded database fan-out.
|
|
63
|
+
*
|
|
64
|
+
* Each entry resolves through `ObjectRegistry.getCollection()` and calls the
|
|
65
|
+
* collection's public `list()` method, preserving interceptors, tenancy, STI,
|
|
66
|
+
* hydration, eager loading, projections, and opt-in collection caching.
|
|
67
|
+
*
|
|
68
|
+
* On failure, no additional queued entry is started. Operations that were
|
|
69
|
+
* already in flight are allowed to settle before the first error is rethrown,
|
|
70
|
+
* so the function never leaves detached database work behind.
|
|
71
|
+
*
|
|
72
|
+
* This function does not compose SQL, cache the plan, or change database pool
|
|
73
|
+
* defaults. It only bounds top-level list-operation concurrency.
|
|
74
|
+
*/
|
|
75
|
+
export declare function executeCollectionReadPlan<const Plan extends SmrtCollectionReadPlan>(plan: Plan, options: ExecuteCollectionReadPlanOptions): Promise<SmrtCollectionReadPlanResult<Plan>>;
|
|
76
|
+
export {};
|
|
77
|
+
//# sourceMappingURL=collection-read-plan.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collection-read-plan.d.ts","sourceRoot":"","sources":["../src/collection-read-plan.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,KAAK,EAEV,eAAe,EACf,eAAe,EACf,eAAe,EAChB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAG3C,KAAK,iBAAiB,GAAG,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAC9D,KAAK,iCAAiC,CAAC,SAAS,SAAS,UAAU,IAAI,IAAI,CACzE,eAAe,CAAC,SAAS,CAAC,EAC1B,QAAQ,CACT,GAAG;IACF,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB,CAAC;AACF,KAAK,kCAAkC,CAAC,SAAS,SAAS,UAAU,IAAI,IAAI,CAC1E,eAAe,CAAC,SAAS,CAAC,EAC1B,QAAQ,GAAG,SAAS,CACrB,GAAG;IACF,MAAM,EAAE,SAAS,eAAe,CAAC,SAAS,CAAC,EAAE,CAAC;IAC9C,OAAO,CAAC,EAAE,KAAK,CAAC;CACjB,CAAC;AACF,KAAK,yBAAyB,CAAC,SAAS,SAAS,UAAU,IACvD,iCAAiC,CAAC,SAAS,CAAC,GAC5C,kCAAkC,CAAC,SAAS,CAAC,CAAC;AAClD,KAAK,sBAAsB,GAAG,yBAAyB,CAAC,iBAAiB,CAAC,CAAC;AAC3E,OAAO,CAAC,MAAM,2BAA2B,EAAE,OAAO,MAAM,CAAC;AAEzD,KAAK,kCAAkC,CACrC,SAAS,SAAS,UAAU,EAC5B,WAAW,SAAS,yBAAyB,CAAC,SAAS,CAAC,GAAG,SAAS,IAEpE,WAAW,SAAS,kCAAkC,CAAC,SAAS,CAAC,GAC7D;IACE,yEAAyE;IACzE,OAAO,EAAE,WAAW,CAAC;CACtB,GACD;IACE,qFAAqF;IACrF,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB,CAAC;AAER;;;;;GAKG;AACH,MAAM,MAAM,2BAA2B,CACrC,SAAS,SAAS,UAAU,GAAG,UAAU,EACzC,WAAW,SACP,yBAAyB,CAAC,SAAS,CAAC,GACpC,SAAS,GAAG,iCAAiC,CAAC,SAAS,CAAC,IAC1D;IACF,iDAAiD;IACjD,SAAS,EAAE,MAAM,CAAC;IAClB,mEAAmE;IACnE,QAAQ,CAAC,CAAC,2BAA2B,CAAC,CAAC,EAAE,SAAS,CAAC;CACpD,GAAG,kCAAkC,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;AAE/D,qDAAqD;AACrD,MAAM,MAAM,sBAAsB,GAAG,MAAM,CACzC,MAAM,EACN;IACE,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,sBAAsB,CAAC;CAClC,CACF,CAAC;AAEF,KAAK,gCAAgC,CAAC,KAAK,IAAI,KAAK,SAAS;IAC3D,QAAQ,CAAC,CAAC,2BAA2B,CAAC,CAAC,EAAE,MAAM,SAAS,CAAC;CAC1D,GACG,SAAS,SAAS,UAAU,GAC1B,SAAS,GACT,UAAU,GACZ,UAAU,CAAC;AAEf,KAAK,iCAAiC,CAAC,KAAK,IAAI,KAAK,SAAS;IAC5D,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,MAAM,CAAA;KAAE,CAAC;CACnC,GACG,MAAM,SAAS,SAAS,eAAe,CACrC,gCAAgC,CAAC,KAAK,CAAC,CACxC,EAAE,GACD,eAAe,CAAC,gCAAgC,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,EAAE,GAClE,KAAK,GACP,gCAAgC,CAAC,KAAK,CAAC,EAAE,CAAC;AAE9C,gEAAgE;AAChE,MAAM,MAAM,4BAA4B,CAAC,IAAI,SAAS,sBAAsB,IAC1E;KACG,GAAG,IAAI,MAAM,IAAI,GAAG,iCAAiC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;CAClE,CAAC;AAEJ,MAAM,WAAW,gCAAgC;IAC/C;;;;OAIG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB,mEAAmE;IACnE,iBAAiB,CAAC,EAAE,gBAAgB,CAAC;CACtC;AAwBD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,yBAAyB,CAC7C,KAAK,CAAC,IAAI,SAAS,sBAAsB,EAEzC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,gCAAgC,GACxC,OAAO,CAAC,4BAA4B,CAAC,IAAI,CAAC,CAAC,CAsD7C"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { ObjectRegistry } from "./registry.js";
|
|
2
|
+
//#region src/collection-read-plan.ts
|
|
3
|
+
async function listCollection(collection, options) {
|
|
4
|
+
if (options?.select !== void 0) return await collection.list(options);
|
|
5
|
+
return await collection.list(options);
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Execute independent collection reads without unbounded database fan-out.
|
|
9
|
+
*
|
|
10
|
+
* Each entry resolves through `ObjectRegistry.getCollection()` and calls the
|
|
11
|
+
* collection's public `list()` method, preserving interceptors, tenancy, STI,
|
|
12
|
+
* hydration, eager loading, projections, and opt-in collection caching.
|
|
13
|
+
*
|
|
14
|
+
* On failure, no additional queued entry is started. Operations that were
|
|
15
|
+
* already in flight are allowed to settle before the first error is rethrown,
|
|
16
|
+
* so the function never leaves detached database work behind.
|
|
17
|
+
*
|
|
18
|
+
* This function does not compose SQL, cache the plan, or change database pool
|
|
19
|
+
* defaults. It only bounds top-level list-operation concurrency.
|
|
20
|
+
*/
|
|
21
|
+
async function executeCollectionReadPlan(plan, options) {
|
|
22
|
+
if (!Number.isInteger(options.maxConcurrency) || options.maxConcurrency <= 0) throw new RangeError("maxConcurrency must be a positive integer");
|
|
23
|
+
const entries = Object.entries(plan);
|
|
24
|
+
if (entries.length === 0) return Object.fromEntries([]);
|
|
25
|
+
let nextIndex = 0;
|
|
26
|
+
let failed = false;
|
|
27
|
+
let firstError;
|
|
28
|
+
const values = new Array(entries.length);
|
|
29
|
+
const runWorker = async () => {
|
|
30
|
+
while (!failed) {
|
|
31
|
+
const entryIndex = nextIndex;
|
|
32
|
+
nextIndex += 1;
|
|
33
|
+
if (entryIndex >= entries.length) return;
|
|
34
|
+
const [, entry] = entries[entryIndex];
|
|
35
|
+
try {
|
|
36
|
+
const value = await listCollection(await ObjectRegistry.getCollection(entry.className, options.collectionOptions), entry.options);
|
|
37
|
+
values[entryIndex] = value;
|
|
38
|
+
} catch (error) {
|
|
39
|
+
if (!failed) {
|
|
40
|
+
failed = true;
|
|
41
|
+
firstError = error;
|
|
42
|
+
}
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
const workerCount = Math.min(options.maxConcurrency, entries.length);
|
|
48
|
+
await Promise.all(Array.from({ length: workerCount }, runWorker));
|
|
49
|
+
if (failed) throw firstError;
|
|
50
|
+
return Object.fromEntries(entries.map(([key], index) => [key, values[index]]));
|
|
51
|
+
}
|
|
52
|
+
//#endregion
|
|
53
|
+
export { executeCollectionReadPlan };
|
|
54
|
+
|
|
55
|
+
//# sourceMappingURL=collection-read-plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collection-read-plan.js","names":[],"sources":["../src/collection-read-plan.ts"],"sourcesContent":["import type { SmrtClassOptions } from './class';\nimport type {\n SmrtCollection,\n SmrtListOptions,\n SmrtSelectedRow,\n SmrtSelectField,\n} from './collection';\nimport type { SmrtObject } from './object';\nimport { ObjectRegistry } from './registry';\n\ntype DynamicSmrtObject = SmrtObject & Record<string, unknown>;\ntype SmrtHydratedCollectionReadOptions<ModelType extends SmrtObject> = Omit<\n SmrtListOptions<ModelType>,\n 'select'\n> & {\n select?: undefined;\n};\ntype SmrtProjectedCollectionReadOptions<ModelType extends SmrtObject> = Omit<\n SmrtListOptions<ModelType>,\n 'select' | 'include'\n> & {\n select: readonly SmrtSelectField<ModelType>[];\n include?: never;\n};\ntype SmrtCollectionReadOptions<ModelType extends SmrtObject> =\n | SmrtHydratedCollectionReadOptions<ModelType>\n | SmrtProjectedCollectionReadOptions<ModelType>;\ntype DynamicSmrtListOptions = SmrtCollectionReadOptions<DynamicSmrtObject>;\ndeclare const smrtCollectionReadPlanModel: unique symbol;\n\ntype SmrtCollectionReadPlanEntryOptions<\n ModelType extends SmrtObject,\n ListOptions extends SmrtCollectionReadOptions<ModelType> | undefined,\n> =\n ListOptions extends SmrtProjectedCollectionReadOptions<ModelType>\n ? {\n /** Projection options forwarded unchanged to `SmrtCollection.list()`. */\n options: ListOptions;\n }\n : {\n /** Standard hydrated-list options forwarded unchanged to `SmrtCollection.list()`. */\n options?: ListOptions;\n };\n\n/**\n * One independent collection read in a bounded read plan.\n *\n * `ModelType` is optional for dynamic registries. Consumers that know the\n * model type can annotate an entry to retain model/projection result typing.\n */\nexport type SmrtCollectionReadPlanEntry<\n ModelType extends SmrtObject = SmrtObject,\n ListOptions extends\n | SmrtCollectionReadOptions<ModelType>\n | undefined = SmrtHydratedCollectionReadOptions<ModelType>,\n> = {\n /** Registered SMRT object or collection name. */\n className: string;\n /** @internal Retains the model type for keyed result inference. */\n readonly [smrtCollectionReadPlanModel]?: ModelType;\n} & SmrtCollectionReadPlanEntryOptions<ModelType, ListOptions>;\n\n/** A keyed group of independent collection reads. */\nexport type SmrtCollectionReadPlan = Record<\n string,\n {\n className: string;\n options?: DynamicSmrtListOptions;\n }\n>;\n\ntype SmrtCollectionReadPlanEntryModel<Entry> = Entry extends {\n readonly [smrtCollectionReadPlanModel]?: infer ModelType;\n}\n ? ModelType extends SmrtObject\n ? ModelType\n : SmrtObject\n : SmrtObject;\n\ntype SmrtCollectionReadPlanEntryResult<Entry> = Entry extends {\n options: { select: infer Select };\n}\n ? Select extends readonly SmrtSelectField<\n SmrtCollectionReadPlanEntryModel<Entry>\n >[]\n ? SmrtSelectedRow<SmrtCollectionReadPlanEntryModel<Entry>, Select>[]\n : never\n : SmrtCollectionReadPlanEntryModel<Entry>[];\n\n/** Results retain the exact keys declared by the input plan. */\nexport type SmrtCollectionReadPlanResult<Plan extends SmrtCollectionReadPlan> =\n {\n [Key in keyof Plan]: SmrtCollectionReadPlanEntryResult<Plan[Key]>;\n };\n\nexport interface ExecuteCollectionReadPlanOptions {\n /**\n * Maximum number of top-level `collection.list()` operations in flight.\n * Must be a positive integer and is intentionally required so callers make\n * workload policy explicit.\n */\n maxConcurrency: number;\n /** Normal options used to resolve every collection in the plan. */\n collectionOptions?: SmrtClassOptions;\n}\n\nasync function listCollection(\n collection: SmrtCollection<DynamicSmrtObject>,\n options: DynamicSmrtListOptions | undefined,\n): Promise<unknown[]> {\n if (options?.select !== undefined) {\n return await collection.list(\n options as DynamicSmrtListOptions & {\n select: readonly SmrtSelectField<DynamicSmrtObject>[];\n include?: never;\n },\n );\n }\n\n return await collection.list(\n options as\n | (Omit<DynamicSmrtListOptions, 'select'> & {\n select?: undefined;\n })\n | undefined,\n );\n}\n\n/**\n * Execute independent collection reads without unbounded database fan-out.\n *\n * Each entry resolves through `ObjectRegistry.getCollection()` and calls the\n * collection's public `list()` method, preserving interceptors, tenancy, STI,\n * hydration, eager loading, projections, and opt-in collection caching.\n *\n * On failure, no additional queued entry is started. Operations that were\n * already in flight are allowed to settle before the first error is rethrown,\n * so the function never leaves detached database work behind.\n *\n * This function does not compose SQL, cache the plan, or change database pool\n * defaults. It only bounds top-level list-operation concurrency.\n */\nexport async function executeCollectionReadPlan<\n const Plan extends SmrtCollectionReadPlan,\n>(\n plan: Plan,\n options: ExecuteCollectionReadPlanOptions,\n): Promise<SmrtCollectionReadPlanResult<Plan>> {\n if (\n !Number.isInteger(options.maxConcurrency) ||\n options.maxConcurrency <= 0\n ) {\n throw new RangeError('maxConcurrency must be a positive integer');\n }\n\n const entries = Object.entries(plan) as [keyof Plan, Plan[keyof Plan]][];\n\n if (entries.length === 0) {\n return Object.fromEntries(\n [],\n ) as unknown as SmrtCollectionReadPlanResult<Plan>;\n }\n\n let nextIndex = 0;\n let failed = false;\n let firstError: unknown;\n const values: unknown[][] = new Array(entries.length);\n\n const runWorker = async (): Promise<void> => {\n while (!failed) {\n const entryIndex = nextIndex;\n nextIndex += 1;\n if (entryIndex >= entries.length) return;\n\n const [, entry] = entries[entryIndex];\n\n try {\n const collection =\n await ObjectRegistry.getCollection<DynamicSmrtObject>(\n entry.className,\n options.collectionOptions,\n );\n const value = await listCollection(collection, entry.options);\n values[entryIndex] = value;\n } catch (error) {\n if (!failed) {\n failed = true;\n firstError = error;\n }\n return;\n }\n }\n };\n\n const workerCount = Math.min(options.maxConcurrency, entries.length);\n await Promise.all(Array.from({ length: workerCount }, runWorker));\n\n if (failed) throw firstError;\n return Object.fromEntries(\n entries.map(([key], index) => [key, values[index]]),\n ) as unknown as SmrtCollectionReadPlanResult<Plan>;\n}\n"],"mappings":";;AA0GA,eAAe,eACb,YACA,SACoB;CACpB,IAAI,SAAS,WAAW,KAAA,GACtB,OAAO,MAAM,WAAW,KACtB,OAIF;CAGF,OAAO,MAAM,WAAW,KACtB,OAKF;AACF;;;;;;;;;;;;;;;AAgBA,eAAsB,0BAGpB,MACA,SAC6C;CAC7C,IACE,CAAC,OAAO,UAAU,QAAQ,cAAc,KACxC,QAAQ,kBAAkB,GAE1B,MAAM,IAAI,WAAW,2CAA2C;CAGlE,MAAM,UAAU,OAAO,QAAQ,IAAI;CAEnC,IAAI,QAAQ,WAAW,GACrB,OAAO,OAAO,YACZ,CAAC,CACH;CAGF,IAAI,YAAY;CAChB,IAAI,SAAS;CACb,IAAI;CACJ,MAAM,SAAsB,IAAI,MAAM,QAAQ,MAAM;CAEpD,MAAM,YAAY,YAA2B;EAC3C,OAAO,CAAC,QAAQ;GACd,MAAM,aAAa;GACnB,aAAa;GACb,IAAI,cAAc,QAAQ,QAAQ;GAElC,MAAM,GAAG,SAAS,QAAQ;GAE1B,IAAI;IAMF,MAAM,QAAQ,MAAM,eAAe,MAJ3B,eAAe,cACnB,MAAM,WACN,QAAQ,iBACV,GAC6C,MAAM,OAAO;IAC5D,OAAO,cAAc;GACvB,SAAS,OAAO;IACd,IAAI,CAAC,QAAQ;KACX,SAAS;KACT,aAAa;IACf;IACA;GACF;EACF;CACF;CAEA,MAAM,cAAc,KAAK,IAAI,QAAQ,gBAAgB,QAAQ,MAAM;CACnE,MAAM,QAAQ,IAAI,MAAM,KAAK,EAAE,QAAQ,YAAY,GAAG,SAAS,CAAC;CAEhE,IAAI,QAAQ,MAAM;CAClB,OAAO,OAAO,YACZ,QAAQ,KAAK,CAAC,MAAM,UAAU,CAAC,KAAK,OAAO,MAAM,CAAC,CACpD;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/consumer-plugin/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAwDnC,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,wBAAwB;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iCAAiC;IACjC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,oDAAoD;IACpD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4BAA4B;IAC5B,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAiBD;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,GAAE,mBAAwB,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/consumer-plugin/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAwDnC,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,wBAAwB;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,iCAAiC;IACjC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,oDAAoD;IACpD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4BAA4B;IAC5B,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAiBD;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,GAAE,mBAAwB,GAAG,MAAM,CAuHtE"}
|
|
@@ -25,6 +25,9 @@ function smrtConsumer(options = {}) {
|
|
|
25
25
|
let typesGenerated = false;
|
|
26
26
|
return {
|
|
27
27
|
name: "smrt-consumer",
|
|
28
|
+
config() {
|
|
29
|
+
return { build: { rollupOptions: { external: [/\.node$/] } } };
|
|
30
|
+
},
|
|
28
31
|
async buildStart() {
|
|
29
32
|
console.log("[smrt:consumer] Initializing SMRT consumer plugin");
|
|
30
33
|
if (packages.length === 0 && !disableScanning) smrtPackages = await discoverSmrtPackages(projectRoot);
|
|
@@ -235,8 +238,22 @@ async function saveAggregatedManifest(manifest, projectRoot) {
|
|
|
235
238
|
async function generateRegistrationFile(manifest, projectRoot) {
|
|
236
239
|
const smrtDir = path.join(projectRoot, ".smrt");
|
|
237
240
|
const registerPath = path.join(smrtDir, "register.js");
|
|
238
|
-
const
|
|
241
|
+
const importBindings = /* @__PURE__ */ new Map();
|
|
242
|
+
const importsByPath = /* @__PURE__ */ new Map();
|
|
243
|
+
let nextImportBinding = 0;
|
|
244
|
+
const getImportBinding = (importPath, exportName) => {
|
|
245
|
+
const key = `${importPath}\0${exportName}`;
|
|
246
|
+
const existing = importBindings.get(key);
|
|
247
|
+
if (existing) return existing;
|
|
248
|
+
const binding = `__smrt_consumer_${nextImportBinding++}`;
|
|
249
|
+
importBindings.set(key, binding);
|
|
250
|
+
const specifiers = importsByPath.get(importPath) ?? /* @__PURE__ */ new Map();
|
|
251
|
+
specifiers.set(exportName, binding);
|
|
252
|
+
importsByPath.set(importPath, specifiers);
|
|
253
|
+
return binding;
|
|
254
|
+
};
|
|
239
255
|
const registrations = [];
|
|
256
|
+
const registrationManifests = {};
|
|
240
257
|
let importedEntryCount = 0;
|
|
241
258
|
let registeredObjectCount = 0;
|
|
242
259
|
const manifestObjects = manifest.objects;
|
|
@@ -280,12 +297,19 @@ async function generateRegistrationFile(manifest, projectRoot) {
|
|
|
280
297
|
const collectionExportName = def.collectionExportName;
|
|
281
298
|
const hasCollection = def.hasCollection;
|
|
282
299
|
const tableName = def.collection || objectName.toLowerCase();
|
|
283
|
-
|
|
284
|
-
|
|
300
|
+
const exportBinding = getImportBinding(importPath, exportName);
|
|
301
|
+
const collectionBinding = hasCollection && collectionExportName ? getImportBinding(importPath, collectionExportName) : void 0;
|
|
285
302
|
importedEntryCount++;
|
|
286
303
|
if (isCollectionClass(def)) continue;
|
|
287
|
-
|
|
288
|
-
|
|
304
|
+
const logicalName = def.className || exportName;
|
|
305
|
+
registrationManifests[objectName] = {
|
|
306
|
+
...manifest,
|
|
307
|
+
packageName: def.packageName,
|
|
308
|
+
packageVersion: def.packageVersion || manifest.packageVersion,
|
|
309
|
+
objects: { [objectName]: def }
|
|
310
|
+
};
|
|
311
|
+
registrations.push(`if (${exportBinding}) ObjectRegistry.register(${exportBinding}, { name: ${JSON.stringify(logicalName)}, packageName: ${JSON.stringify(def.packageName)}, _manifest: smrtRegistrationManifests[${JSON.stringify(objectName)}], _manifestKey: ${JSON.stringify(objectName)} });`);
|
|
312
|
+
if (collectionBinding) registrations.push(`if (${collectionBinding}) ObjectRegistry.registerCollection('${tableName}', ${collectionBinding});`);
|
|
289
313
|
registeredObjectCount++;
|
|
290
314
|
}
|
|
291
315
|
if (importedEntryCount === 0) {
|
|
@@ -293,6 +317,10 @@ async function generateRegistrationFile(manifest, projectRoot) {
|
|
|
293
317
|
return;
|
|
294
318
|
}
|
|
295
319
|
const registeredObjectLabel = registeredObjectCount === 1 ? "object" : "objects";
|
|
320
|
+
const sortedImports = Array.from(importsByPath.entries()).sort(([left], [right]) => left.localeCompare(right));
|
|
321
|
+
const imports = sortedImports.map(([importPath], index) => `import * as __smrt_provider_${index} from '${importPath}';`);
|
|
322
|
+
const importDeclarations = sortedImports.flatMap(([, specifiers], index) => Array.from(specifiers.entries()).sort(([left], [right]) => left.localeCompare(right)).map(([exportName, binding]) => `const ${binding} = getSmrtExport(__smrt_provider_${index}, ${JSON.stringify(exportName)});`));
|
|
323
|
+
const registrationManifestLiteral = JSON.stringify(JSON.stringify(registrationManifests));
|
|
296
324
|
const content = `/**
|
|
297
325
|
* Auto-generated by @happyvertical/smrt-core/consumer-plugin
|
|
298
326
|
* DO NOT EDIT - This file is regenerated on every build
|
|
@@ -305,6 +333,17 @@ import { ObjectRegistry } from '@happyvertical/smrt-core';
|
|
|
305
333
|
|
|
306
334
|
${imports.join("\n")}
|
|
307
335
|
|
|
336
|
+
/**
|
|
337
|
+
* @param {Record<string, unknown>} provider
|
|
338
|
+
* @param {string} exportName
|
|
339
|
+
* @returns {any}
|
|
340
|
+
*/
|
|
341
|
+
const getSmrtExport = (provider, exportName) =>
|
|
342
|
+
typeof provider[exportName] === 'function' ? provider[exportName] : undefined;
|
|
343
|
+
${importDeclarations.join("\n")}
|
|
344
|
+
|
|
345
|
+
const smrtRegistrationManifests = JSON.parse(${registrationManifestLiteral});
|
|
346
|
+
|
|
308
347
|
// Register all objects (executed during module evaluation)
|
|
309
348
|
${registrations.join("\n")}
|
|
310
349
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../src/consumer-plugin/index.ts"],"sourcesContent":["/**\n * Vite plugin for consuming SMRT packages\n * Solves virtual module resolution in downstream projects\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { Plugin } from 'vite';\nimport { generateDeclarations } from '../prebuild/index.js';\nimport type { SmartObjectManifest } from '../scanner/types.js';\nimport { MANIFEST_TIMESTAMP } from '../scanner/types.js';\nimport { generateClientModule } from '../vite-plugin/generated-client.js';\n\n/**\n * Loosely-typed view of an object definition as carried by an external\n * package's static manifest. The static manifests are read from JSON at the\n * package boundary, so only the fields this plugin consumes are typed; the\n * index signature preserves any additional fields (e.g. for spreads). This is\n * a structural superset of a manifest `SmartObjectDefinition` plus the\n * consumer-only `hasCollection` marker.\n */\ninterface ConsumerObjectDefinition {\n className?: string;\n packageName?: string;\n packageVersion?: string;\n qualifiedName?: string;\n importPath?: string;\n exportName?: string;\n collectionExportName?: string;\n hasCollection?: boolean;\n collection?: string;\n extends?: string;\n extendsQualified?: string;\n extendsTypeArg?: string;\n [key: string]: unknown;\n}\n\n/**\n * Aggregated manifest assembled by the consumer plugin from one or more\n * external package manifests. Loosely typed because the inputs originate from\n * JSON read at the package boundary.\n */\ninterface ConsumerManifest {\n version: string;\n timestamp: number;\n packageName?: string;\n packageVersion?: string;\n objects: Record<string, ConsumerObjectDefinition>;\n}\n\n/**\n * Minimal structural shape of a parsed `package.json` consumed here (name,\n * version, and the export map used to derive import paths). The index\n * signature keeps the remaining fields accessible.\n */\ninterface ConsumerPackageJson {\n name?: string;\n version?: string;\n main?: string;\n exports?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\nexport interface SmrtConsumerOptions {\n /** SMRT packages to scan (e.g., ['@my-org/products', '@my-org/content']) */\n packages?: string[];\n /** Generate TypeScript declarations */\n generateTypes?: boolean;\n /** Output directory for generated types */\n typesDir?: string;\n /** Project root path */\n projectRoot?: string;\n /** SvelteKit integration mode */\n svelteKit?: boolean;\n /**\n * Apply kebab-case to generated custom-method URL segments. This must match\n * the producer plugin's `svelteKit.kebabRoutes` setting.\n */\n kebabRoutes?: boolean;\n /** Use static types only (for federation builds) */\n staticTypes?: boolean;\n /** Disable file scanning */\n disableScanning?: boolean;\n}\n\n// Distinct resolved ids per plugin (#1795). smrtPlugin resolves\n// `@happyvertical/smrt-virt-*` to `\\0smrt:*`; if this consumer plugin also\n// resolved its `@smrt/*` specifiers to `\\0smrt:*` the two virtual modules would\n// share a rollup id, and in standalone/federation builds the consumer's\n// fallback `load` would non-deterministically win and shadow smrtPlugin's real\n// module. Namespacing the consumer ids (`\\0smrt-consumer:*`) keeps them\n// separate so each plugin only ever loads its own module.\nconst VIRTUAL_MODULES = {\n '@smrt/routes': 'smrt-consumer:routes',\n '@smrt/client': 'smrt-consumer:client',\n '@smrt/mcp': 'smrt-consumer:mcp',\n '@smrt/types': 'smrt-consumer:types',\n '@smrt/manifest': 'smrt-consumer:manifest',\n};\n\n/**\n * Consumer plugin for projects that use SMRT packages\n */\nexport function smrtConsumer(options: SmrtConsumerOptions = {}): Plugin {\n const {\n packages = [],\n generateTypes = true,\n typesDir = 'src/types/smrt-generated',\n projectRoot = process.cwd(),\n disableScanning = false,\n kebabRoutes = false,\n } = options;\n\n let smrtPackages: string[] = [];\n let typeManifest: ConsumerManifest | null = null;\n let typesGenerated = false;\n\n return {\n name: 'smrt-consumer',\n\n async buildStart() {\n console.log('[smrt:consumer] Initializing SMRT consumer plugin');\n\n // Discover SMRT packages if not explicitly specified\n if (packages.length === 0 && !disableScanning) {\n smrtPackages = await discoverSmrtPackages(projectRoot);\n } else {\n smrtPackages = packages;\n }\n\n if (smrtPackages.length > 0) {\n console.log(\n `[smrt:consumer] Found SMRT packages: ${smrtPackages.join(', ')}`,\n );\n\n // Aggregate type manifests from discovered packages\n typeManifest = await aggregateTypeManifests(smrtPackages, projectRoot);\n\n // Save aggregated manifest for CLI discovery\n await saveAggregatedManifest(typeManifest, projectRoot);\n\n // Generate registration file for CLI class loading\n await generateRegistrationFile(typeManifest, projectRoot);\n\n // Generate types if requested\n if (generateTypes && !typesGenerated) {\n await generateProjectTypes(typeManifest, typesDir, projectRoot);\n typesGenerated = true;\n }\n } else {\n console.log('[smrt:consumer] No SMRT packages found');\n typeManifest = {\n version: '1.0.0',\n timestamp: MANIFEST_TIMESTAMP,\n objects: {},\n };\n }\n },\n\n resolveId(id, _importer) {\n // Resolve virtual modules to generated type declarations\n if (id in VIRTUAL_MODULES) {\n const typeFileName = getTypeFileName(id);\n const typePath = path.join(projectRoot, typesDir, typeFileName);\n\n // If types file exists, resolve to it\n if (fs.existsSync(typePath)) {\n return typePath;\n }\n\n // Otherwise use virtual module ID for runtime resolution\n return `\\0${VIRTUAL_MODULES[id as keyof typeof VIRTUAL_MODULES]}`;\n }\n return null;\n },\n\n async load(id) {\n // Handle virtual modules if types aren't available\n const cleanId = id.startsWith('\\0') ? id.slice(1) : id;\n\n if (!typeManifest) {\n typeManifest = {\n version: '1.0.0',\n timestamp: MANIFEST_TIMESTAMP,\n objects: {},\n };\n }\n\n switch (cleanId) {\n case 'smrt-consumer:routes':\n return generateFallbackRoutesModule();\n\n case 'smrt-consumer:client':\n return generateFallbackClientModule(typeManifest, { kebabRoutes });\n\n case 'smrt-consumer:mcp':\n return generateFallbackMcpModule();\n\n case 'smrt-consumer:types':\n return generateFallbackTypesModule(typeManifest);\n\n case 'smrt-consumer:manifest':\n return generateFallbackManifestModule(typeManifest);\n\n default:\n return null;\n }\n },\n };\n}\n\n/**\n * Discover SMRT packages from a consumer app's dependencies.\n *\n * Intentional split (#1579): this **consumer-plugin** path is async and\n * resolves SMRT packages from the downstream app's `package.json` dependency\n * names (`@have/`/`smrt` heuristic + `hasSmrtManifest` probe) inside the Vite\n * consumer plugin. It is deliberately separate from the build-time\n * `discoverSmrtPackages()` in `src/manifest/discover-smrt-packages.ts` — a\n * synchronous, lockfile-cached `node_modules` manifest scan used for manifest\n * generation. Different inputs, contexts, and lifecycles, not duplicated logic.\n */\nasync function discoverSmrtPackages(projectRoot: string): Promise<string[]> {\n const packages: string[] = [];\n const nodeModulesPath = path.join(projectRoot, 'node_modules');\n\n if (!fs.existsSync(nodeModulesPath)) {\n return packages;\n }\n\n try {\n // Check package.json for workspace dependencies\n const packageJsonPath = path.join(projectRoot, 'package.json');\n if (fs.existsSync(packageJsonPath)) {\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));\n const allDeps = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n ...packageJson.peerDependencies,\n };\n\n // Look for packages that likely contain SMRT objects\n for (const [name, version] of Object.entries(allDeps)) {\n if (\n typeof version === 'string' &&\n (name.includes('smrt') ||\n name.includes('@have/') ||\n (await hasSmrtManifest(nodeModulesPath, name)))\n ) {\n packages.push(name);\n }\n }\n }\n } catch (error) {\n console.warn('[smrt:consumer] Error discovering packages:', error);\n }\n\n return packages;\n}\n\n/**\n * Check if a package has SMRT manifest\n */\nasync function hasSmrtManifest(\n nodeModulesPath: string,\n packageName: string,\n): Promise<boolean> {\n const packagePath = path.join(nodeModulesPath, packageName);\n const manifestPath = path.join(\n packagePath,\n 'dist',\n 'manifest',\n 'static-manifest.js',\n );\n return fs.existsSync(manifestPath);\n}\n\n/**\n * Aggregate type manifests from multiple packages\n */\nasync function aggregateTypeManifests(\n packages: string[],\n projectRoot: string,\n): Promise<ConsumerManifest> {\n const aggregatedManifest: ConsumerManifest = {\n version: '1.0.0',\n timestamp: MANIFEST_TIMESTAMP,\n objects: {},\n };\n\n for (const packageName of packages) {\n try {\n const packageDir = path.join(projectRoot, 'node_modules', packageName);\n\n // Load package.json for version and export information\n const packageJsonPath = path.join(packageDir, 'package.json');\n let packageJson: ConsumerPackageJson;\n try {\n const packageJsonContent = fs.readFileSync(packageJsonPath, 'utf-8');\n packageJson = JSON.parse(packageJsonContent) as ConsumerPackageJson;\n } catch {\n console.warn(\n `[smrt:consumer] Could not read package.json for ${packageName}`,\n );\n continue;\n }\n\n // Try multiple manifest locations\n const manifestCandidates = [\n path.join(packageDir, 'dist', 'manifest', 'static-manifest.js'),\n path.join(packageDir, 'dist', 'manifest.json'),\n path.join(packageDir, 'manifest.json'),\n ];\n\n for (const manifestPath of manifestCandidates) {\n if (fs.existsSync(manifestPath)) {\n // Import or read the manifest\n let manifest: Partial<ConsumerManifest> | undefined;\n if (manifestPath.endsWith('.js')) {\n const manifestModule = await import(manifestPath);\n manifest = manifestModule.staticManifest || manifestModule.default;\n } else {\n const manifestContent = fs.readFileSync(manifestPath, 'utf-8');\n manifest = JSON.parse(manifestContent) as Partial<ConsumerManifest>;\n }\n\n if (manifest?.objects) {\n console.log(\n `[smrt:consumer] Loaded manifest from ${packageName} (${Object.keys(manifest.objects).length} objects)`,\n );\n\n // ENHANCED: Preserve package metadata for each object\n for (const [objectName, objectDef] of Object.entries(\n manifest.objects,\n )) {\n const def = objectDef;\n\n aggregatedManifest.objects[objectName] = {\n ...def,\n // Ensure package metadata is preserved/set\n packageName:\n def.packageName || manifest.packageName || packageName,\n packageVersion:\n def.packageVersion ||\n manifest.packageVersion ||\n packageJson.version,\n // Add fallback import paths if missing\n importPath: def.importPath || determineImportPath(packageJson),\n exportName: def.exportName || def.className || objectName,\n collectionExportName:\n def.collectionExportName ||\n `${def.className || objectName}Collection`,\n };\n }\n\n break; // Use first found manifest for this package\n }\n }\n }\n } catch (error) {\n console.warn(\n `[smrt:consumer] Error loading manifest from ${packageName}:`,\n error,\n );\n }\n }\n\n return aggregatedManifest;\n}\n\n/**\n * Determine import path from package.json\n */\nfunction determineImportPath(packageJson: ConsumerPackageJson): string {\n const packageName = packageJson.name;\n\n if (!packageName) {\n throw new Error('Package name not found in package.json');\n }\n\n // Strategy 1: Check for specific exports\n if (packageJson.exports) {\n // Check for objects export\n if (packageJson.exports['./objects']) {\n return `${packageName}/objects`;\n }\n\n // Check for main export\n const mainExport = packageJson.exports['.'];\n if (mainExport) {\n // Handle conditional exports\n if (typeof mainExport === 'object' && mainExport !== null) {\n const conditional = mainExport as Record<string, unknown>;\n if (conditional.import) {\n return packageName;\n }\n if (conditional.default) {\n return packageName;\n }\n }\n return packageName;\n }\n }\n\n // Strategy 2: Check main field\n if (packageJson.main) {\n return packageName;\n }\n\n // Strategy 3: Fallback to package name\n return packageName;\n}\n\n/**\n * Save aggregated manifest to .smrt/manifest.json for CLI discovery.\n *\n * Merge-preserving: `smrtPlugin()` writes the project's own scanned objects\n * to the same file (`writeLocalManifest`, issue #963), and both writes happen\n * in parallel `buildStart` hooks — so a plain overwrite here would clobber\n * the local objects whenever this plugin's write lands last (issue #1760\n * review). Local field metadata would then silently vanish from CLI schema\n * commands and from server runtimes that seed `.smrt/manifest.json`, dropping\n * domain columns on write. This function therefore only ADDS/refreshes the\n * external-package entries it owns and preserves everything else already in\n * the file (including the top-level `packageName` the local write sets).\n */\nasync function saveAggregatedManifest(\n manifest: ConsumerManifest,\n projectRoot: string,\n): Promise<void> {\n const smrtDir = path.join(projectRoot, '.smrt');\n const manifestPath = path.join(smrtDir, 'manifest.json');\n\n try {\n // Create .smrt directory if it doesn't exist\n if (!fs.existsSync(smrtDir)) {\n fs.mkdirSync(smrtDir, { recursive: true });\n }\n\n // Merge with whatever is on disk: existing entries (typically the local\n // project's objects written by smrtPlugin) are preserved; aggregated\n // external entries win for the qualified names this plugin owns.\n let merged: ConsumerManifest = manifest;\n if (fs.existsSync(manifestPath)) {\n try {\n const existing = JSON.parse(\n fs.readFileSync(manifestPath, 'utf-8'),\n ) as Partial<ConsumerManifest>;\n if (existing && typeof existing.objects === 'object') {\n merged = {\n ...existing,\n ...manifest,\n // The aggregated manifest carries no packageName; keep the local\n // project's (used as the manifest cache key at runtime).\n ...(existing.packageName\n ? { packageName: existing.packageName }\n : {}),\n objects: { ...existing.objects, ...manifest.objects },\n };\n }\n } catch {\n // Unreadable/corrupt existing file — fall back to a plain write.\n }\n }\n\n // Write manifest\n fs.writeFileSync(manifestPath, JSON.stringify(merged, null, 2), 'utf-8');\n\n console.log(\n `[smrt:consumer] Saved aggregated manifest to .smrt/manifest.json (${Object.keys(merged.objects).length} objects)`,\n );\n } catch (error) {\n console.warn('[smrt:consumer] Failed to save aggregated manifest:', error);\n }\n}\n\n/**\n * Generate registration file for CLI class loading\n *\n * Creates .smrt/register.js with static imports and registrations\n * for all external SMRT objects discovered during build.\n */\nasync function generateRegistrationFile(\n manifest: ConsumerManifest,\n projectRoot: string,\n): Promise<void> {\n const smrtDir = path.join(projectRoot, '.smrt');\n const registerPath = path.join(smrtDir, 'register.js');\n\n // Build import statements and registrations\n const imports: string[] = [];\n const registrations: string[] = [];\n let importedEntryCount = 0;\n let registeredObjectCount = 0;\n\n const manifestObjects = manifest.objects;\n const manifestObjectLookup = new Map<string, ConsumerObjectDefinition>();\n for (const [key, def] of Object.entries(manifestObjects)) {\n const candidate = def;\n const lookupKeys = [\n key,\n key.includes(':') ? key.split(':').pop() : undefined,\n candidate.qualifiedName,\n candidate.className,\n candidate.exportName,\n ];\n\n for (const lookupKey of lookupKeys) {\n if (lookupKey && !manifestObjectLookup.has(lookupKey)) {\n manifestObjectLookup.set(lookupKey, candidate);\n }\n }\n }\n\n const collectionClassMemo = new WeakMap<object, boolean>();\n\n const isCollectionClass = (\n def: ConsumerObjectDefinition | undefined,\n seen = new Set<string>(),\n ): boolean => {\n if (!def || typeof def !== 'object') {\n return false;\n }\n\n const cached = collectionClassMemo.get(def);\n if (cached !== undefined) {\n return cached;\n }\n\n if (\n def?.extends === 'SmrtCollection' ||\n def?.extendsTypeArg !== undefined\n ) {\n collectionClassMemo.set(def, true);\n return true;\n }\n\n const parentName = def?.extendsQualified || def?.extends;\n if (!parentName || seen.has(parentName)) {\n collectionClassMemo.set(def, false);\n return false;\n }\n seen.add(parentName);\n\n const parentDef = manifestObjectLookup.get(parentName);\n const isCollection = parentDef ? isCollectionClass(parentDef, seen) : false;\n collectionClassMemo.set(def, isCollection);\n\n return isCollection;\n };\n\n for (const [objectName, objectDef] of Object.entries(manifestObjects)) {\n const def = objectDef;\n\n // Skip local objects (they're imported from local entry point)\n if (!def.packageName || def.packageName === manifest.packageName) {\n continue;\n }\n\n const importPath = def.importPath || def.packageName;\n const exportName = def.exportName || def.className || objectName;\n const collectionExportName = def.collectionExportName;\n const hasCollection = def.hasCollection; // Check if collection class actually exists\n const tableName = def.collection || objectName.toLowerCase();\n\n // Generate import statement\n // Only import collection if it exists (hasCollection is truthy)\n if (hasCollection && collectionExportName) {\n imports.push(\n `import { ${exportName}, ${collectionExportName} } from '${importPath}';`,\n );\n } else {\n imports.push(`import { ${exportName} } from '${importPath}';`);\n }\n importedEntryCount++;\n\n if (isCollectionClass(def)) {\n continue;\n }\n\n // Generate registration calls\n // The import above already triggers the @smrt() decorator which registers the class\n // properly with its simple name and qualified name. We call register() again with\n // an empty config just to ensure the class is registered (in case it lacks a decorator).\n // Do NOT pass { name: qualifiedName } as that creates a separate registry entry.\n registrations.push(\n `ObjectRegistry.register(${exportName}, { name: ${JSON.stringify(exportName)}, packageName: ${JSON.stringify(def.packageName)} });`,\n );\n\n // Only register collection if it exists\n if (hasCollection && collectionExportName) {\n registrations.push(\n `ObjectRegistry.registerCollection('${tableName}', ${collectionExportName});`,\n );\n }\n\n registeredObjectCount++;\n }\n\n // Skip generation if no external entries\n if (importedEntryCount === 0) {\n console.log('[smrt:consumer] No external entries - skipping register.js');\n return;\n }\n\n const registeredObjectLabel =\n registeredObjectCount === 1 ? 'object' : 'objects';\n\n // Generate file content\n const content = `/**\n * Auto-generated by @happyvertical/smrt-core/consumer-plugin\n * DO NOT EDIT - This file is regenerated on every build\n *\n * Registers SMRT objects from external packages for CLI discovery.\n * Generated at: ${new Date().toISOString()}\n */\n\nimport { ObjectRegistry } from '@happyvertical/smrt-core';\n\n${imports.join('\\n')}\n\n// Register all objects (executed during module evaluation)\n${registrations.join('\\n')}\n\nexport function registerAll() {\n // Objects are already registered during module evaluation\n console.log('[smrt:register] Registered ${registeredObjectCount} external ${registeredObjectLabel}');\n}\n`;\n\n // Create .smrt directory if needed\n if (!fs.existsSync(smrtDir)) {\n fs.mkdirSync(smrtDir, { recursive: true });\n }\n\n // Write registration file\n fs.writeFileSync(registerPath, content, 'utf-8');\n\n console.log(\n `[smrt:consumer] Generated .smrt/register.js with ${importedEntryCount} external entries (${registeredObjectCount} registered ${registeredObjectLabel})`,\n );\n}\n\n/**\n * Generate project-specific types\n */\nasync function generateProjectTypes(\n typeManifest: ConsumerManifest,\n typesDir: string,\n projectRoot: string,\n): Promise<void> {\n if (!typeManifest || Object.keys(typeManifest.objects).length === 0) {\n console.log(\n '[smrt:consumer] No SMRT objects found, skipping type generation',\n );\n return;\n }\n\n await generateDeclarations({\n // The aggregated manifest is a runtime SMRT manifest assembled from external\n // package manifests; it is intentionally typed loosely at the JSON boundary,\n // so narrow it to the declaration generator's strict manifest shape here.\n manifest: typeManifest as unknown as SmartObjectManifest,\n outDir: typesDir,\n projectRoot,\n includeVirtualModules: true,\n includeObjectTypes: true,\n });\n\n console.log(\n `[smrt:consumer] Generated types for ${Object.keys(typeManifest.objects).length} objects`,\n );\n}\n\n/**\n * Get type file name for virtual module\n */\nfunction getTypeFileName(virtualModule: string): string {\n const moduleMap: Record<string, string> = {\n '@smrt/routes': 'smrt-routes.d.ts',\n '@smrt/client': 'smrt-client.d.ts',\n '@smrt/mcp': 'smrt-mcp.d.ts',\n '@smrt/types': 'smrt-types.d.ts',\n '@smrt/manifest': 'smrt-manifest.d.ts',\n };\n return moduleMap[virtualModule] || 'smrt-unknown.d.ts';\n}\n\n/**\n * Fallback modules for when types aren't available\n */\nfunction generateFallbackRoutesModule(): string {\n return `\n// Fallback routes module\nexport function setupRoutes(app) {\n console.warn('[smrt:consumer] No routes available - SMRT packages may not be properly configured');\n}\nexport default setupRoutes;\n`;\n}\n\nfunction generateFallbackClientModule(\n manifest: ConsumerManifest,\n options: { kebabRoutes?: boolean } = {},\n): string {\n const objects = Object.entries(manifest?.objects || {});\n if (objects.length === 0) {\n return `\n// Fallback client module\nexport function createClient(basePath = '/api/v1') {\n console.warn('[smrt:consumer] No API client available - SMRT packages may not be properly configured');\n return {};\n}\nexport default createClient;\n`;\n }\n\n return generateClientModule(manifest as unknown as SmartObjectManifest, {\n kebabRoutes: options.kebabRoutes,\n });\n}\n\nfunction generateFallbackMcpModule(): string {\n return `\n// Fallback MCP module\nexport const tools = [];\nexport function createMCPServer() {\n console.warn('[smrt:consumer] No MCP tools available - SMRT packages may not be properly configured');\n return { name: 'smrt-consumer', version: '1.0.0', tools: [] };\n}\nexport default createMCPServer;\n`;\n}\n\nfunction generateFallbackTypesModule(manifest: ConsumerManifest): string {\n const objects = Object.entries(manifest?.objects || {});\n if (objects.length === 0) {\n return `// No types available`;\n }\n\n // Generate basic interfaces\n const interfaces = objects.map(([_name, obj]) => {\n return `export interface ${obj.className}Data {\n id?: string;\n created_at?: string;\n updated_at?: string;\n [key: string]: any;\n}`;\n });\n\n return interfaces.join('\\n\\n');\n}\n\nfunction generateFallbackManifestModule(manifest: ConsumerManifest): string {\n return `\n// Auto-generated manifest from SMRT consumer\nexport const manifest = ${JSON.stringify(manifest, null, 2)};\nexport default manifest;\n`;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../src/consumer-plugin/index.ts"],"sourcesContent":["/**\n * Vite plugin for consuming SMRT packages\n * Solves virtual module resolution in downstream projects\n */\n\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { Plugin } from 'vite';\nimport { generateDeclarations } from '../prebuild/index.js';\nimport type { SmartObjectManifest } from '../scanner/types.js';\nimport { MANIFEST_TIMESTAMP } from '../scanner/types.js';\nimport { generateClientModule } from '../vite-plugin/generated-client.js';\n\n/**\n * Loosely-typed view of an object definition as carried by an external\n * package's static manifest. The static manifests are read from JSON at the\n * package boundary, so only the fields this plugin consumes are typed; the\n * index signature preserves any additional fields (e.g. for spreads). This is\n * a structural superset of a manifest `SmartObjectDefinition` plus the\n * consumer-only `hasCollection` marker.\n */\ninterface ConsumerObjectDefinition {\n className?: string;\n packageName?: string;\n packageVersion?: string;\n qualifiedName?: string;\n importPath?: string;\n exportName?: string;\n collectionExportName?: string;\n hasCollection?: boolean;\n collection?: string;\n extends?: string;\n extendsQualified?: string;\n extendsTypeArg?: string;\n [key: string]: unknown;\n}\n\n/**\n * Aggregated manifest assembled by the consumer plugin from one or more\n * external package manifests. Loosely typed because the inputs originate from\n * JSON read at the package boundary.\n */\ninterface ConsumerManifest {\n version: string;\n timestamp: number;\n packageName?: string;\n packageVersion?: string;\n objects: Record<string, ConsumerObjectDefinition>;\n}\n\n/**\n * Minimal structural shape of a parsed `package.json` consumed here (name,\n * version, and the export map used to derive import paths). The index\n * signature keeps the remaining fields accessible.\n */\ninterface ConsumerPackageJson {\n name?: string;\n version?: string;\n main?: string;\n exports?: Record<string, unknown>;\n [key: string]: unknown;\n}\n\nexport interface SmrtConsumerOptions {\n /** SMRT packages to scan (e.g., ['@my-org/products', '@my-org/content']) */\n packages?: string[];\n /** Generate TypeScript declarations */\n generateTypes?: boolean;\n /** Output directory for generated types */\n typesDir?: string;\n /** Project root path */\n projectRoot?: string;\n /** SvelteKit integration mode */\n svelteKit?: boolean;\n /**\n * Apply kebab-case to generated custom-method URL segments. This must match\n * the producer plugin's `svelteKit.kebabRoutes` setting.\n */\n kebabRoutes?: boolean;\n /** Use static types only (for federation builds) */\n staticTypes?: boolean;\n /** Disable file scanning */\n disableScanning?: boolean;\n}\n\n// Distinct resolved ids per plugin (#1795). smrtPlugin resolves\n// `@happyvertical/smrt-virt-*` to `\\0smrt:*`; if this consumer plugin also\n// resolved its `@smrt/*` specifiers to `\\0smrt:*` the two virtual modules would\n// share a rollup id, and in standalone/federation builds the consumer's\n// fallback `load` would non-deterministically win and shadow smrtPlugin's real\n// module. Namespacing the consumer ids (`\\0smrt-consumer:*`) keeps them\n// separate so each plugin only ever loads its own module.\nconst VIRTUAL_MODULES = {\n '@smrt/routes': 'smrt-consumer:routes',\n '@smrt/client': 'smrt-consumer:client',\n '@smrt/mcp': 'smrt-consumer:mcp',\n '@smrt/types': 'smrt-consumer:types',\n '@smrt/manifest': 'smrt-consumer:manifest',\n};\n\n/**\n * Consumer plugin for projects that use SMRT packages\n */\nexport function smrtConsumer(options: SmrtConsumerOptions = {}): Plugin {\n const {\n packages = [],\n generateTypes = true,\n typesDir = 'src/types/smrt-generated',\n projectRoot = process.cwd(),\n disableScanning = false,\n kebabRoutes = false,\n } = options;\n\n let smrtPackages: string[] = [];\n let typeManifest: ConsumerManifest | null = null;\n let typesGenerated = false;\n\n return {\n name: 'smrt-consumer',\n\n config() {\n return {\n build: {\n rollupOptions: {\n // Runtime registration evaluates provider entry points so their\n // exact constructors can be registered. Leave optional native\n // provider binaries to Node instead of parsing them as JavaScript.\n external: [/\\.node$/],\n },\n },\n };\n },\n\n async buildStart() {\n console.log('[smrt:consumer] Initializing SMRT consumer plugin');\n\n // Discover SMRT packages if not explicitly specified\n if (packages.length === 0 && !disableScanning) {\n smrtPackages = await discoverSmrtPackages(projectRoot);\n } else {\n smrtPackages = packages;\n }\n\n if (smrtPackages.length > 0) {\n console.log(\n `[smrt:consumer] Found SMRT packages: ${smrtPackages.join(', ')}`,\n );\n\n // Aggregate type manifests from discovered packages\n typeManifest = await aggregateTypeManifests(smrtPackages, projectRoot);\n\n // Save aggregated manifest for CLI discovery\n await saveAggregatedManifest(typeManifest, projectRoot);\n\n // Generate registration file for CLI class loading\n await generateRegistrationFile(typeManifest, projectRoot);\n\n // Generate types if requested\n if (generateTypes && !typesGenerated) {\n await generateProjectTypes(typeManifest, typesDir, projectRoot);\n typesGenerated = true;\n }\n } else {\n console.log('[smrt:consumer] No SMRT packages found');\n typeManifest = {\n version: '1.0.0',\n timestamp: MANIFEST_TIMESTAMP,\n objects: {},\n };\n }\n },\n\n resolveId(id, _importer) {\n // Resolve virtual modules to generated type declarations\n if (id in VIRTUAL_MODULES) {\n const typeFileName = getTypeFileName(id);\n const typePath = path.join(projectRoot, typesDir, typeFileName);\n\n // If types file exists, resolve to it\n if (fs.existsSync(typePath)) {\n return typePath;\n }\n\n // Otherwise use virtual module ID for runtime resolution\n return `\\0${VIRTUAL_MODULES[id as keyof typeof VIRTUAL_MODULES]}`;\n }\n return null;\n },\n\n async load(id) {\n // Handle virtual modules if types aren't available\n const cleanId = id.startsWith('\\0') ? id.slice(1) : id;\n\n if (!typeManifest) {\n typeManifest = {\n version: '1.0.0',\n timestamp: MANIFEST_TIMESTAMP,\n objects: {},\n };\n }\n\n switch (cleanId) {\n case 'smrt-consumer:routes':\n return generateFallbackRoutesModule();\n\n case 'smrt-consumer:client':\n return generateFallbackClientModule(typeManifest, { kebabRoutes });\n\n case 'smrt-consumer:mcp':\n return generateFallbackMcpModule();\n\n case 'smrt-consumer:types':\n return generateFallbackTypesModule(typeManifest);\n\n case 'smrt-consumer:manifest':\n return generateFallbackManifestModule(typeManifest);\n\n default:\n return null;\n }\n },\n };\n}\n\n/**\n * Discover SMRT packages from a consumer app's dependencies.\n *\n * Intentional split (#1579): this **consumer-plugin** path is async and\n * resolves SMRT packages from the downstream app's `package.json` dependency\n * names (`@have/`/`smrt` heuristic + `hasSmrtManifest` probe) inside the Vite\n * consumer plugin. It is deliberately separate from the build-time\n * `discoverSmrtPackages()` in `src/manifest/discover-smrt-packages.ts` — a\n * synchronous, lockfile-cached `node_modules` manifest scan used for manifest\n * generation. Different inputs, contexts, and lifecycles, not duplicated logic.\n */\nasync function discoverSmrtPackages(projectRoot: string): Promise<string[]> {\n const packages: string[] = [];\n const nodeModulesPath = path.join(projectRoot, 'node_modules');\n\n if (!fs.existsSync(nodeModulesPath)) {\n return packages;\n }\n\n try {\n // Check package.json for workspace dependencies\n const packageJsonPath = path.join(projectRoot, 'package.json');\n if (fs.existsSync(packageJsonPath)) {\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));\n const allDeps = {\n ...packageJson.dependencies,\n ...packageJson.devDependencies,\n ...packageJson.peerDependencies,\n };\n\n // Look for packages that likely contain SMRT objects\n for (const [name, version] of Object.entries(allDeps)) {\n if (\n typeof version === 'string' &&\n (name.includes('smrt') ||\n name.includes('@have/') ||\n (await hasSmrtManifest(nodeModulesPath, name)))\n ) {\n packages.push(name);\n }\n }\n }\n } catch (error) {\n console.warn('[smrt:consumer] Error discovering packages:', error);\n }\n\n return packages;\n}\n\n/**\n * Check if a package has SMRT manifest\n */\nasync function hasSmrtManifest(\n nodeModulesPath: string,\n packageName: string,\n): Promise<boolean> {\n const packagePath = path.join(nodeModulesPath, packageName);\n const manifestPath = path.join(\n packagePath,\n 'dist',\n 'manifest',\n 'static-manifest.js',\n );\n return fs.existsSync(manifestPath);\n}\n\n/**\n * Aggregate type manifests from multiple packages\n */\nasync function aggregateTypeManifests(\n packages: string[],\n projectRoot: string,\n): Promise<ConsumerManifest> {\n const aggregatedManifest: ConsumerManifest = {\n version: '1.0.0',\n timestamp: MANIFEST_TIMESTAMP,\n objects: {},\n };\n\n for (const packageName of packages) {\n try {\n const packageDir = path.join(projectRoot, 'node_modules', packageName);\n\n // Load package.json for version and export information\n const packageJsonPath = path.join(packageDir, 'package.json');\n let packageJson: ConsumerPackageJson;\n try {\n const packageJsonContent = fs.readFileSync(packageJsonPath, 'utf-8');\n packageJson = JSON.parse(packageJsonContent) as ConsumerPackageJson;\n } catch {\n console.warn(\n `[smrt:consumer] Could not read package.json for ${packageName}`,\n );\n continue;\n }\n\n // Try multiple manifest locations\n const manifestCandidates = [\n path.join(packageDir, 'dist', 'manifest', 'static-manifest.js'),\n path.join(packageDir, 'dist', 'manifest.json'),\n path.join(packageDir, 'manifest.json'),\n ];\n\n for (const manifestPath of manifestCandidates) {\n if (fs.existsSync(manifestPath)) {\n // Import or read the manifest\n let manifest: Partial<ConsumerManifest> | undefined;\n if (manifestPath.endsWith('.js')) {\n const manifestModule = await import(manifestPath);\n manifest = manifestModule.staticManifest || manifestModule.default;\n } else {\n const manifestContent = fs.readFileSync(manifestPath, 'utf-8');\n manifest = JSON.parse(manifestContent) as Partial<ConsumerManifest>;\n }\n\n if (manifest?.objects) {\n console.log(\n `[smrt:consumer] Loaded manifest from ${packageName} (${Object.keys(manifest.objects).length} objects)`,\n );\n\n // ENHANCED: Preserve package metadata for each object\n for (const [objectName, objectDef] of Object.entries(\n manifest.objects,\n )) {\n const def = objectDef;\n\n aggregatedManifest.objects[objectName] = {\n ...def,\n // Ensure package metadata is preserved/set\n packageName:\n def.packageName || manifest.packageName || packageName,\n packageVersion:\n def.packageVersion ||\n manifest.packageVersion ||\n packageJson.version,\n // Add fallback import paths if missing\n importPath: def.importPath || determineImportPath(packageJson),\n exportName: def.exportName || def.className || objectName,\n collectionExportName:\n def.collectionExportName ||\n `${def.className || objectName}Collection`,\n };\n }\n\n break; // Use first found manifest for this package\n }\n }\n }\n } catch (error) {\n console.warn(\n `[smrt:consumer] Error loading manifest from ${packageName}:`,\n error,\n );\n }\n }\n\n return aggregatedManifest;\n}\n\n/**\n * Determine import path from package.json\n */\nfunction determineImportPath(packageJson: ConsumerPackageJson): string {\n const packageName = packageJson.name;\n\n if (!packageName) {\n throw new Error('Package name not found in package.json');\n }\n\n // Strategy 1: Check for specific exports\n if (packageJson.exports) {\n // Check for objects export\n if (packageJson.exports['./objects']) {\n return `${packageName}/objects`;\n }\n\n // Check for main export\n const mainExport = packageJson.exports['.'];\n if (mainExport) {\n // Handle conditional exports\n if (typeof mainExport === 'object' && mainExport !== null) {\n const conditional = mainExport as Record<string, unknown>;\n if (conditional.import) {\n return packageName;\n }\n if (conditional.default) {\n return packageName;\n }\n }\n return packageName;\n }\n }\n\n // Strategy 2: Check main field\n if (packageJson.main) {\n return packageName;\n }\n\n // Strategy 3: Fallback to package name\n return packageName;\n}\n\n/**\n * Save aggregated manifest to .smrt/manifest.json for CLI discovery.\n *\n * Merge-preserving: `smrtPlugin()` writes the project's own scanned objects\n * to the same file (`writeLocalManifest`, issue #963), and both writes happen\n * in parallel `buildStart` hooks — so a plain overwrite here would clobber\n * the local objects whenever this plugin's write lands last (issue #1760\n * review). Local field metadata would then silently vanish from CLI schema\n * commands and from server runtimes that seed `.smrt/manifest.json`, dropping\n * domain columns on write. This function therefore only ADDS/refreshes the\n * external-package entries it owns and preserves everything else already in\n * the file (including the top-level `packageName` the local write sets).\n */\nasync function saveAggregatedManifest(\n manifest: ConsumerManifest,\n projectRoot: string,\n): Promise<void> {\n const smrtDir = path.join(projectRoot, '.smrt');\n const manifestPath = path.join(smrtDir, 'manifest.json');\n\n try {\n // Create .smrt directory if it doesn't exist\n if (!fs.existsSync(smrtDir)) {\n fs.mkdirSync(smrtDir, { recursive: true });\n }\n\n // Merge with whatever is on disk: existing entries (typically the local\n // project's objects written by smrtPlugin) are preserved; aggregated\n // external entries win for the qualified names this plugin owns.\n let merged: ConsumerManifest = manifest;\n if (fs.existsSync(manifestPath)) {\n try {\n const existing = JSON.parse(\n fs.readFileSync(manifestPath, 'utf-8'),\n ) as Partial<ConsumerManifest>;\n if (existing && typeof existing.objects === 'object') {\n merged = {\n ...existing,\n ...manifest,\n // The aggregated manifest carries no packageName; keep the local\n // project's (used as the manifest cache key at runtime).\n ...(existing.packageName\n ? { packageName: existing.packageName }\n : {}),\n objects: { ...existing.objects, ...manifest.objects },\n };\n }\n } catch {\n // Unreadable/corrupt existing file — fall back to a plain write.\n }\n }\n\n // Write manifest\n fs.writeFileSync(manifestPath, JSON.stringify(merged, null, 2), 'utf-8');\n\n console.log(\n `[smrt:consumer] Saved aggregated manifest to .smrt/manifest.json (${Object.keys(merged.objects).length} objects)`,\n );\n } catch (error) {\n console.warn('[smrt:consumer] Failed to save aggregated manifest:', error);\n }\n}\n\n/**\n * Generate registration file for CLI class loading\n *\n * Creates .smrt/register.js with static imports and registrations\n * for all external SMRT objects discovered during build.\n */\nasync function generateRegistrationFile(\n manifest: ConsumerManifest,\n projectRoot: string,\n): Promise<void> {\n const smrtDir = path.join(projectRoot, '.smrt');\n const registerPath = path.join(smrtDir, 'register.js');\n\n // Bind every imported symbol to a generated local name. Aggregated manifests\n // may contain same-named exports from different packages (and may list a\n // collection both beside its object and as its own manifest entry), so using\n // provider export names as local bindings can produce invalid duplicate\n // imports in a production consumer bundle.\n const importBindings = new Map<string, string>();\n const importsByPath = new Map<string, Map<string, string>>();\n let nextImportBinding = 0;\n const getImportBinding = (importPath: string, exportName: string): string => {\n const key = `${importPath}\\0${exportName}`;\n const existing = importBindings.get(key);\n if (existing) return existing;\n const binding = `__smrt_consumer_${nextImportBinding++}`;\n importBindings.set(key, binding);\n const specifiers =\n importsByPath.get(importPath) ?? new Map<string, string>();\n specifiers.set(exportName, binding);\n importsByPath.set(importPath, specifiers);\n return binding;\n };\n\n const registrations: string[] = [];\n const registrationManifests: Record<string, ConsumerManifest> = {};\n let importedEntryCount = 0;\n let registeredObjectCount = 0;\n\n const manifestObjects = manifest.objects;\n const manifestObjectLookup = new Map<string, ConsumerObjectDefinition>();\n for (const [key, def] of Object.entries(manifestObjects)) {\n const candidate = def;\n const lookupKeys = [\n key,\n key.includes(':') ? key.split(':').pop() : undefined,\n candidate.qualifiedName,\n candidate.className,\n candidate.exportName,\n ];\n\n for (const lookupKey of lookupKeys) {\n if (lookupKey && !manifestObjectLookup.has(lookupKey)) {\n manifestObjectLookup.set(lookupKey, candidate);\n }\n }\n }\n\n const collectionClassMemo = new WeakMap<object, boolean>();\n\n const isCollectionClass = (\n def: ConsumerObjectDefinition | undefined,\n seen = new Set<string>(),\n ): boolean => {\n if (!def || typeof def !== 'object') {\n return false;\n }\n\n const cached = collectionClassMemo.get(def);\n if (cached !== undefined) {\n return cached;\n }\n\n if (\n def?.extends === 'SmrtCollection' ||\n def?.extendsTypeArg !== undefined\n ) {\n collectionClassMemo.set(def, true);\n return true;\n }\n\n const parentName = def?.extendsQualified || def?.extends;\n if (!parentName || seen.has(parentName)) {\n collectionClassMemo.set(def, false);\n return false;\n }\n seen.add(parentName);\n\n const parentDef = manifestObjectLookup.get(parentName);\n const isCollection = parentDef ? isCollectionClass(parentDef, seen) : false;\n collectionClassMemo.set(def, isCollection);\n\n return isCollection;\n };\n\n for (const [objectName, objectDef] of Object.entries(manifestObjects)) {\n const def = objectDef;\n\n // Skip local objects (they're imported from local entry point)\n if (!def.packageName || def.packageName === manifest.packageName) {\n continue;\n }\n\n const importPath = def.importPath || def.packageName;\n const exportName = def.exportName || def.className || objectName;\n const collectionExportName = def.collectionExportName;\n const hasCollection = def.hasCollection; // Check if collection class actually exists\n const tableName = def.collection || objectName.toLowerCase();\n\n const exportBinding = getImportBinding(importPath, exportName);\n const collectionBinding =\n hasCollection && collectionExportName\n ? getImportBinding(importPath, collectionExportName)\n : undefined;\n importedEntryCount++;\n\n if (isCollectionClass(def)) {\n continue;\n }\n\n const logicalName = def.className || exportName;\n registrationManifests[objectName] = {\n ...manifest,\n packageName: def.packageName,\n packageVersion: def.packageVersion || manifest.packageVersion,\n objects: { [objectName]: def },\n };\n\n // Import evaluation triggers the provider decorator first. The explicit\n // constructor/package/key tuple then promotes that exact constructor with\n // its isolated manifest, which is stable across Rollup name deconfliction.\n registrations.push(\n `if (${exportBinding}) ObjectRegistry.register(${exportBinding}, { name: ${JSON.stringify(logicalName)}, packageName: ${JSON.stringify(def.packageName)}, _manifest: smrtRegistrationManifests[${JSON.stringify(objectName)}], _manifestKey: ${JSON.stringify(objectName)} });`,\n );\n\n // Only register collection if it exists\n if (collectionBinding) {\n registrations.push(\n `if (${collectionBinding}) ObjectRegistry.registerCollection('${tableName}', ${collectionBinding});`,\n );\n }\n\n registeredObjectCount++;\n }\n\n // Skip generation if no external entries\n if (importedEntryCount === 0) {\n console.log('[smrt:consumer] No external entries - skipping register.js');\n return;\n }\n\n const registeredObjectLabel =\n registeredObjectCount === 1 ? 'object' : 'objects';\n const sortedImports = Array.from(importsByPath.entries()).sort(\n ([left], [right]) => left.localeCompare(right),\n );\n const imports = sortedImports.map(\n ([importPath], index) =>\n `import * as __smrt_provider_${index} from '${importPath}';`,\n );\n const importDeclarations = sortedImports.flatMap(([, specifiers], index) =>\n Array.from(specifiers.entries())\n .sort(([left], [right]) => left.localeCompare(right))\n .map(\n ([exportName, binding]) =>\n `const ${binding} = getSmrtExport(__smrt_provider_${index}, ${JSON.stringify(exportName)});`,\n ),\n );\n const registrationManifestLiteral = JSON.stringify(\n JSON.stringify(registrationManifests),\n );\n\n // Generate file content\n const content = `/**\n * Auto-generated by @happyvertical/smrt-core/consumer-plugin\n * DO NOT EDIT - This file is regenerated on every build\n *\n * Registers SMRT objects from external packages for CLI discovery.\n * Generated at: ${new Date().toISOString()}\n */\n\nimport { ObjectRegistry } from '@happyvertical/smrt-core';\n\n${imports.join('\\n')}\n\n/**\n * @param {Record<string, unknown>} provider\n * @param {string} exportName\n * @returns {any}\n */\nconst getSmrtExport = (provider, exportName) =>\n typeof provider[exportName] === 'function' ? provider[exportName] : undefined;\n${importDeclarations.join('\\n')}\n\nconst smrtRegistrationManifests = JSON.parse(${registrationManifestLiteral});\n\n// Register all objects (executed during module evaluation)\n${registrations.join('\\n')}\n\nexport function registerAll() {\n // Objects are already registered during module evaluation\n console.log('[smrt:register] Registered ${registeredObjectCount} external ${registeredObjectLabel}');\n}\n`;\n\n // Create .smrt directory if needed\n if (!fs.existsSync(smrtDir)) {\n fs.mkdirSync(smrtDir, { recursive: true });\n }\n\n // Write registration file\n fs.writeFileSync(registerPath, content, 'utf-8');\n\n console.log(\n `[smrt:consumer] Generated .smrt/register.js with ${importedEntryCount} external entries (${registeredObjectCount} registered ${registeredObjectLabel})`,\n );\n}\n\n/**\n * Generate project-specific types\n */\nasync function generateProjectTypes(\n typeManifest: ConsumerManifest,\n typesDir: string,\n projectRoot: string,\n): Promise<void> {\n if (!typeManifest || Object.keys(typeManifest.objects).length === 0) {\n console.log(\n '[smrt:consumer] No SMRT objects found, skipping type generation',\n );\n return;\n }\n\n await generateDeclarations({\n // The aggregated manifest is a runtime SMRT manifest assembled from external\n // package manifests; it is intentionally typed loosely at the JSON boundary,\n // so narrow it to the declaration generator's strict manifest shape here.\n manifest: typeManifest as unknown as SmartObjectManifest,\n outDir: typesDir,\n projectRoot,\n includeVirtualModules: true,\n includeObjectTypes: true,\n });\n\n console.log(\n `[smrt:consumer] Generated types for ${Object.keys(typeManifest.objects).length} objects`,\n );\n}\n\n/**\n * Get type file name for virtual module\n */\nfunction getTypeFileName(virtualModule: string): string {\n const moduleMap: Record<string, string> = {\n '@smrt/routes': 'smrt-routes.d.ts',\n '@smrt/client': 'smrt-client.d.ts',\n '@smrt/mcp': 'smrt-mcp.d.ts',\n '@smrt/types': 'smrt-types.d.ts',\n '@smrt/manifest': 'smrt-manifest.d.ts',\n };\n return moduleMap[virtualModule] || 'smrt-unknown.d.ts';\n}\n\n/**\n * Fallback modules for when types aren't available\n */\nfunction generateFallbackRoutesModule(): string {\n return `\n// Fallback routes module\nexport function setupRoutes(app) {\n console.warn('[smrt:consumer] No routes available - SMRT packages may not be properly configured');\n}\nexport default setupRoutes;\n`;\n}\n\nfunction generateFallbackClientModule(\n manifest: ConsumerManifest,\n options: { kebabRoutes?: boolean } = {},\n): string {\n const objects = Object.entries(manifest?.objects || {});\n if (objects.length === 0) {\n return `\n// Fallback client module\nexport function createClient(basePath = '/api/v1') {\n console.warn('[smrt:consumer] No API client available - SMRT packages may not be properly configured');\n return {};\n}\nexport default createClient;\n`;\n }\n\n return generateClientModule(manifest as unknown as SmartObjectManifest, {\n kebabRoutes: options.kebabRoutes,\n });\n}\n\nfunction generateFallbackMcpModule(): string {\n return `\n// Fallback MCP module\nexport const tools = [];\nexport function createMCPServer() {\n console.warn('[smrt:consumer] No MCP tools available - SMRT packages may not be properly configured');\n return { name: 'smrt-consumer', version: '1.0.0', tools: [] };\n}\nexport default createMCPServer;\n`;\n}\n\nfunction generateFallbackTypesModule(manifest: ConsumerManifest): string {\n const objects = Object.entries(manifest?.objects || {});\n if (objects.length === 0) {\n return `// No types available`;\n }\n\n // Generate basic interfaces\n const interfaces = objects.map(([_name, obj]) => {\n return `export interface ${obj.className}Data {\n id?: string;\n created_at?: string;\n updated_at?: string;\n [key: string]: any;\n}`;\n });\n\n return interfaces.join('\\n\\n');\n}\n\nfunction generateFallbackManifestModule(manifest: ConsumerManifest): string {\n return `\n// Auto-generated manifest from SMRT consumer\nexport const manifest = ${JSON.stringify(manifest, null, 2)};\nexport default manifest;\n`;\n}\n"],"mappings":";;;;;;;;;;AA4FA,IAAM,kBAAkB;CACtB,gBAAgB;CAChB,gBAAgB;CAChB,aAAa;CACb,eAAe;CACf,kBAAkB;AACpB;;;;AAKA,SAAgB,aAAa,UAA+B,CAAC,GAAW;CACtE,MAAM,EACJ,WAAW,CAAC,GACZ,gBAAgB,MAChB,WAAW,4BACX,cAAc,QAAQ,IAAI,GAC1B,kBAAkB,OAClB,cAAc,UACZ;CAEJ,IAAI,eAAyB,CAAC;CAC9B,IAAI,eAAwC;CAC5C,IAAI,iBAAiB;CAErB,OAAO;EACL,MAAM;EAEN,SAAS;GACP,OAAO,EACL,OAAO,EACL,eAAe,EAIb,UAAU,CAAC,SAAS,EACtB,EACF,EACF;EACF;EAEA,MAAM,aAAa;GACjB,QAAQ,IAAI,mDAAmD;GAG/D,IAAI,SAAS,WAAW,KAAK,CAAC,iBAC5B,eAAe,MAAM,qBAAqB,WAAW;QAErD,eAAe;GAGjB,IAAI,aAAa,SAAS,GAAG;IAC3B,QAAQ,IACN,wCAAwC,aAAa,KAAK,IAAI,GAChE;IAGA,eAAe,MAAM,uBAAuB,cAAc,WAAW;IAGrE,MAAM,uBAAuB,cAAc,WAAW;IAGtD,MAAM,yBAAyB,cAAc,WAAW;IAGxD,IAAI,iBAAiB,CAAC,gBAAgB;KACpC,MAAM,qBAAqB,cAAc,UAAU,WAAW;KAC9D,iBAAiB;IACnB;GACF,OAAO;IACL,QAAQ,IAAI,wCAAwC;IACpD,eAAe;KACb,SAAS;KACT,WAAA;KACA,SAAS,CAAC;IACZ;GACF;EACF;EAEA,UAAU,IAAI,WAAW;GAEvB,IAAI,MAAM,iBAAiB;IACzB,MAAM,eAAe,gBAAgB,EAAE;IACvC,MAAM,WAAW,KAAK,KAAK,aAAa,UAAU,YAAY;IAG9D,IAAI,GAAG,WAAW,QAAQ,GACxB,OAAO;IAIT,OAAO,KAAK,gBAAgB;GAC9B;GACA,OAAO;EACT;EAEA,MAAM,KAAK,IAAI;GAEb,MAAM,UAAU,GAAG,WAAW,IAAI,IAAI,GAAG,MAAM,CAAC,IAAI;GAEpD,IAAI,CAAC,cACH,eAAe;IACb,SAAS;IACT,WAAA;IACA,SAAS,CAAC;GACZ;GAGF,QAAQ,SAAR;IACE,KAAK,wBACH,OAAO,6BAA6B;IAEtC,KAAK,wBACH,OAAO,6BAA6B,cAAc,EAAE,YAAY,CAAC;IAEnE,KAAK,qBACH,OAAO,0BAA0B;IAEnC,KAAK,uBACH,OAAO,4BAA4B,YAAY;IAEjD,KAAK,0BACH,OAAO,+BAA+B,YAAY;IAEpD,SACE,OAAO;GACX;EACF;CACF;AACF;;;;;;;;;;;;AAaA,eAAe,qBAAqB,aAAwC;CAC1E,MAAM,WAAqB,CAAC;CAC5B,MAAM,kBAAkB,KAAK,KAAK,aAAa,cAAc;CAE7D,IAAI,CAAC,GAAG,WAAW,eAAe,GAChC,OAAO;CAGT,IAAI;EAEF,MAAM,kBAAkB,KAAK,KAAK,aAAa,cAAc;EAC7D,IAAI,GAAG,WAAW,eAAe,GAAG;GAClC,MAAM,cAAc,KAAK,MAAM,GAAG,aAAa,iBAAiB,OAAO,CAAC;GACxE,MAAM,UAAU;IACd,GAAG,YAAY;IACf,GAAG,YAAY;IACf,GAAG,YAAY;GACjB;GAGA,KAAK,MAAM,CAAC,MAAM,YAAY,OAAO,QAAQ,OAAO,GAClD,IACE,OAAO,YAAY,aAClB,KAAK,SAAS,MAAM,KACnB,KAAK,SAAS,QAAQ,KACrB,MAAM,gBAAgB,iBAAiB,IAAI,IAE9C,SAAS,KAAK,IAAI;EAGxB;CACF,SAAS,OAAO;EACd,QAAQ,KAAK,+CAA+C,KAAK;CACnE;CAEA,OAAO;AACT;;;;AAKA,eAAe,gBACb,iBACA,aACkB;CAClB,MAAM,cAAc,KAAK,KAAK,iBAAiB,WAAW;CAC1D,MAAM,eAAe,KAAK,KACxB,aACA,QACA,YACA,oBACF;CACA,OAAO,GAAG,WAAW,YAAY;AACnC;;;;AAKA,eAAe,uBACb,UACA,aAC2B;CAC3B,MAAM,qBAAuC;EAC3C,SAAS;EACT,WAAA;EACA,SAAS,CAAC;CACZ;CAEA,KAAK,MAAM,eAAe,UACxB,IAAI;EACF,MAAM,aAAa,KAAK,KAAK,aAAa,gBAAgB,WAAW;EAGrE,MAAM,kBAAkB,KAAK,KAAK,YAAY,cAAc;EAC5D,IAAI;EACJ,IAAI;GACF,MAAM,qBAAqB,GAAG,aAAa,iBAAiB,OAAO;GACnE,cAAc,KAAK,MAAM,kBAAkB;EAC7C,QAAQ;GACN,QAAQ,KACN,mDAAmD,aACrD;GACA;EACF;EAGA,MAAM,qBAAqB;GACzB,KAAK,KAAK,YAAY,QAAQ,YAAY,oBAAoB;GAC9D,KAAK,KAAK,YAAY,QAAQ,eAAe;GAC7C,KAAK,KAAK,YAAY,eAAe;EACvC;EAEA,KAAK,MAAM,gBAAgB,oBACzB,IAAI,GAAG,WAAW,YAAY,GAAG;GAE/B,IAAI;GACJ,IAAI,aAAa,SAAS,KAAK,GAAG;IAChC,MAAM,iBAAiB,MAAM,OAAO;IACpC,WAAW,eAAe,kBAAkB,eAAe;GAC7D,OAAO;IACL,MAAM,kBAAkB,GAAG,aAAa,cAAc,OAAO;IAC7D,WAAW,KAAK,MAAM,eAAe;GACvC;GAEA,IAAI,UAAU,SAAS;IACrB,QAAQ,IACN,wCAAwC,YAAY,IAAI,OAAO,KAAK,SAAS,OAAO,CAAC,CAAC,OAAO,UAC/F;IAGA,KAAK,MAAM,CAAC,YAAY,cAAc,OAAO,QAC3C,SAAS,OACX,GAAG;KACD,MAAM,MAAM;KAEZ,mBAAmB,QAAQ,cAAc;MACvC,GAAG;MAEH,aACE,IAAI,eAAe,SAAS,eAAe;MAC7C,gBACE,IAAI,kBACJ,SAAS,kBACT,YAAY;MAEd,YAAY,IAAI,cAAc,oBAAoB,WAAW;MAC7D,YAAY,IAAI,cAAc,IAAI,aAAa;MAC/C,sBACE,IAAI,wBACJ,GAAG,IAAI,aAAa,WAAW;KACnC;IACF;IAEA;GACF;EACF;CAEJ,SAAS,OAAO;EACd,QAAQ,KACN,+CAA+C,YAAY,IAC3D,KACF;CACF;CAGF,OAAO;AACT;;;;AAKA,SAAS,oBAAoB,aAA0C;CACrE,MAAM,cAAc,YAAY;CAEhC,IAAI,CAAC,aACH,MAAM,IAAI,MAAM,wCAAwC;CAI1D,IAAI,YAAY,SAAS;EAEvB,IAAI,YAAY,QAAQ,cACtB,OAAO,GAAG,YAAY;EAIxB,MAAM,aAAa,YAAY,QAAQ;EACvC,IAAI,YAAY;GAEd,IAAI,OAAO,eAAe,YAAY,eAAe,MAAM;IACzD,MAAM,cAAc;IACpB,IAAI,YAAY,QACd,OAAO;IAET,IAAI,YAAY,SACd,OAAO;GAEX;GACA,OAAO;EACT;CACF;CAGA,IAAI,YAAY,MACd,OAAO;CAIT,OAAO;AACT;;;;;;;;;;;;;;AAeA,eAAe,uBACb,UACA,aACe;CACf,MAAM,UAAU,KAAK,KAAK,aAAa,OAAO;CAC9C,MAAM,eAAe,KAAK,KAAK,SAAS,eAAe;CAEvD,IAAI;EAEF,IAAI,CAAC,GAAG,WAAW,OAAO,GACxB,GAAG,UAAU,SAAS,EAAE,WAAW,KAAK,CAAC;EAM3C,IAAI,SAA2B;EAC/B,IAAI,GAAG,WAAW,YAAY,GAC5B,IAAI;GACF,MAAM,WAAW,KAAK,MACpB,GAAG,aAAa,cAAc,OAAO,CACvC;GACA,IAAI,YAAY,OAAO,SAAS,YAAY,UAC1C,SAAS;IACP,GAAG;IACH,GAAG;IAGH,GAAI,SAAS,cACT,EAAE,aAAa,SAAS,YAAY,IACpC,CAAC;IACL,SAAS;KAAE,GAAG,SAAS;KAAS,GAAG,SAAS;IAAQ;GACtD;EAEJ,QAAQ,CAER;EAIF,GAAG,cAAc,cAAc,KAAK,UAAU,QAAQ,MAAM,CAAC,GAAG,OAAO;EAEvE,QAAQ,IACN,qEAAqE,OAAO,KAAK,OAAO,OAAO,CAAC,CAAC,OAAO,UAC1G;CACF,SAAS,OAAO;EACd,QAAQ,KAAK,uDAAuD,KAAK;CAC3E;AACF;;;;;;;AAQA,eAAe,yBACb,UACA,aACe;CACf,MAAM,UAAU,KAAK,KAAK,aAAa,OAAO;CAC9C,MAAM,eAAe,KAAK,KAAK,SAAS,aAAa;CAOrD,MAAM,iCAAiB,IAAI,IAAoB;CAC/C,MAAM,gCAAgB,IAAI,IAAiC;CAC3D,IAAI,oBAAoB;CACxB,MAAM,oBAAoB,YAAoB,eAA+B;EAC3E,MAAM,MAAM,GAAG,WAAW,IAAI;EAC9B,MAAM,WAAW,eAAe,IAAI,GAAG;EACvC,IAAI,UAAU,OAAO;EACrB,MAAM,UAAU,mBAAmB;EACnC,eAAe,IAAI,KAAK,OAAO;EAC/B,MAAM,aACJ,cAAc,IAAI,UAAU,qBAAK,IAAI,IAAoB;EAC3D,WAAW,IAAI,YAAY,OAAO;EAClC,cAAc,IAAI,YAAY,UAAU;EACxC,OAAO;CACT;CAEA,MAAM,gBAA0B,CAAC;CACjC,MAAM,wBAA0D,CAAC;CACjE,IAAI,qBAAqB;CACzB,IAAI,wBAAwB;CAE5B,MAAM,kBAAkB,SAAS;CACjC,MAAM,uCAAuB,IAAI,IAAsC;CACvE,KAAK,MAAM,CAAC,KAAK,QAAQ,OAAO,QAAQ,eAAe,GAAG;EACxD,MAAM,YAAY;EAClB,MAAM,aAAa;GACjB;GACA,IAAI,SAAS,GAAG,IAAI,IAAI,MAAM,GAAG,CAAC,CAAC,IAAI,IAAI,KAAA;GAC3C,UAAU;GACV,UAAU;GACV,UAAU;EACZ;EAEA,KAAK,MAAM,aAAa,YACtB,IAAI,aAAa,CAAC,qBAAqB,IAAI,SAAS,GAClD,qBAAqB,IAAI,WAAW,SAAS;CAGnD;CAEA,MAAM,sCAAsB,IAAI,QAAyB;CAEzD,MAAM,qBACJ,KACA,uBAAO,IAAI,IAAY,MACX;EACZ,IAAI,CAAC,OAAO,OAAO,QAAQ,UACzB,OAAO;EAGT,MAAM,SAAS,oBAAoB,IAAI,GAAG;EAC1C,IAAI,WAAW,KAAA,GACb,OAAO;EAGT,IACE,KAAK,YAAY,oBACjB,KAAK,mBAAmB,KAAA,GACxB;GACA,oBAAoB,IAAI,KAAK,IAAI;GACjC,OAAO;EACT;EAEA,MAAM,aAAa,KAAK,oBAAoB,KAAK;EACjD,IAAI,CAAC,cAAc,KAAK,IAAI,UAAU,GAAG;GACvC,oBAAoB,IAAI,KAAK,KAAK;GAClC,OAAO;EACT;EACA,KAAK,IAAI,UAAU;EAEnB,MAAM,YAAY,qBAAqB,IAAI,UAAU;EACrD,MAAM,eAAe,YAAY,kBAAkB,WAAW,IAAI,IAAI;EACtE,oBAAoB,IAAI,KAAK,YAAY;EAEzC,OAAO;CACT;CAEA,KAAK,MAAM,CAAC,YAAY,cAAc,OAAO,QAAQ,eAAe,GAAG;EACrE,MAAM,MAAM;EAGZ,IAAI,CAAC,IAAI,eAAe,IAAI,gBAAgB,SAAS,aACnD;EAGF,MAAM,aAAa,IAAI,cAAc,IAAI;EACzC,MAAM,aAAa,IAAI,cAAc,IAAI,aAAa;EACtD,MAAM,uBAAuB,IAAI;EACjC,MAAM,gBAAgB,IAAI;EAC1B,MAAM,YAAY,IAAI,cAAc,WAAW,YAAY;EAE3D,MAAM,gBAAgB,iBAAiB,YAAY,UAAU;EAC7D,MAAM,oBACJ,iBAAiB,uBACb,iBAAiB,YAAY,oBAAoB,IACjD,KAAA;EACN;EAEA,IAAI,kBAAkB,GAAG,GACvB;EAGF,MAAM,cAAc,IAAI,aAAa;EACrC,sBAAsB,cAAc;GAClC,GAAG;GACH,aAAa,IAAI;GACjB,gBAAgB,IAAI,kBAAkB,SAAS;GAC/C,SAAS,GAAG,aAAa,IAAI;EAC/B;EAKA,cAAc,KACZ,OAAO,cAAc,4BAA4B,cAAc,YAAY,KAAK,UAAU,WAAW,EAAE,iBAAiB,KAAK,UAAU,IAAI,WAAW,EAAE,yCAAyC,KAAK,UAAU,UAAU,EAAE,mBAAmB,KAAK,UAAU,UAAU,EAAE,KAC5Q;EAGA,IAAI,mBACF,cAAc,KACZ,OAAO,kBAAkB,uCAAuC,UAAU,KAAK,kBAAkB,GACnG;EAGF;CACF;CAGA,IAAI,uBAAuB,GAAG;EAC5B,QAAQ,IAAI,4DAA4D;EACxE;CACF;CAEA,MAAM,wBACJ,0BAA0B,IAAI,WAAW;CAC3C,MAAM,gBAAgB,MAAM,KAAK,cAAc,QAAQ,CAAC,CAAC,CAAC,MACvD,CAAC,OAAO,CAAC,WAAW,KAAK,cAAc,KAAK,CAC/C;CACA,MAAM,UAAU,cAAc,KAC3B,CAAC,aAAa,UACb,+BAA+B,MAAM,SAAS,WAAW,GAC7D;CACA,MAAM,qBAAqB,cAAc,SAAS,GAAG,aAAa,UAChE,MAAM,KAAK,WAAW,QAAQ,CAAC,CAAC,CAC7B,MAAM,CAAC,OAAO,CAAC,WAAW,KAAK,cAAc,KAAK,CAAC,CAAC,CACpD,KACE,CAAC,YAAY,aACZ,SAAS,QAAQ,mCAAmC,MAAM,IAAI,KAAK,UAAU,UAAU,EAAE,GAC7F,CACJ;CACA,MAAM,8BAA8B,KAAK,UACvC,KAAK,UAAU,qBAAqB,CACtC;CAGA,MAAM,UAAU;;;;;oCAKC,IAAI,KAAK,EAAA,CAAE,YAAY,EAAE;;;;;EAK1C,QAAQ,KAAK,IAAI,EAAE;;;;;;;;;EASnB,mBAAmB,KAAK,IAAI,EAAE;;+CAEe,4BAA4B;;;EAGzE,cAAc,KAAK,IAAI,EAAE;;;;4CAIiB,sBAAsB,YAAY,sBAAsB;;;CAKlG,IAAI,CAAC,GAAG,WAAW,OAAO,GACxB,GAAG,UAAU,SAAS,EAAE,WAAW,KAAK,CAAC;CAI3C,GAAG,cAAc,cAAc,SAAS,OAAO;CAE/C,QAAQ,IACN,oDAAoD,mBAAmB,qBAAqB,sBAAsB,cAAc,sBAAsB,EACxJ;AACF;;;;AAKA,eAAe,qBACb,cACA,UACA,aACe;CACf,IAAI,CAAC,gBAAgB,OAAO,KAAK,aAAa,OAAO,CAAC,CAAC,WAAW,GAAG;EACnE,QAAQ,IACN,iEACF;EACA;CACF;CAEA,MAAM,qBAAqB;EAIzB,UAAU;EACV,QAAQ;EACR;EACA,uBAAuB;EACvB,oBAAoB;CACtB,CAAC;CAED,QAAQ,IACN,uCAAuC,OAAO,KAAK,aAAa,OAAO,CAAC,CAAC,OAAO,SAClF;AACF;;;;AAKA,SAAS,gBAAgB,eAA+B;CAQtD,OAAO;EANL,gBAAgB;EAChB,gBAAgB;EAChB,aAAa;EACb,eAAe;EACf,kBAAkB;CAEb,EAAU,kBAAkB;AACrC;;;;AAKA,SAAS,+BAAuC;CAC9C,OAAO;;;;;;;AAOT;AAEA,SAAS,6BACP,UACA,UAAqC,CAAC,GAC9B;CAER,IADgB,OAAO,QAAQ,UAAU,WAAW,CAAC,CACjD,CAAA,CAAQ,WAAW,GACrB,OAAO;;;;;;;;CAUT,OAAO,qBAAqB,UAA4C,EACtE,aAAa,QAAQ,YACvB,CAAC;AACH;AAEA,SAAS,4BAAoC;CAC3C,OAAO;;;;;;;;;AAST;AAEA,SAAS,4BAA4B,UAAoC;CACvE,MAAM,UAAU,OAAO,QAAQ,UAAU,WAAW,CAAC,CAAC;CACtD,IAAI,QAAQ,WAAW,GACrB,OAAO;CAaT,OATmB,QAAQ,KAAK,CAAC,OAAO,SAAS;EAC/C,OAAO,oBAAoB,IAAI,UAAU;;;;;;CAM3C,CAEO,CAAA,CAAW,KAAK,MAAM;AAC/B;AAEA,SAAS,+BAA+B,UAAoC;CAC1E,OAAO;;0BAEiB,KAAK,UAAU,UAAU,MAAM,CAAC,EAAE;;;AAG5D"}
|
package/dist/index.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ export { applyOneToManyChildAccessors, childAccessorName, } from './child-access
|
|
|
22
22
|
export * from './class';
|
|
23
23
|
export * from './collection';
|
|
24
24
|
export { broadcastCacheInvalidation, CACHE_INVALIDATION_CHANNEL, type CollectionCacheConfig, ensureCacheInvalidationListener, getCacheGeneration, invalidateCollectionCache, resetCollectionCache, resolveDbCacheKey, stopCacheInvalidationListeners, } from './collection-cache';
|
|
25
|
+
export * from './collection-read-plan';
|
|
25
26
|
export type { AiUsageConfig, GlobalSignalConfig, MetricsConfig, PubSubConfig, } from './config';
|
|
26
27
|
export { config } from './config';
|
|
27
28
|
export { type DatabaseConfig, isDatabaseInterface, type ResolveDatabaseOptions, resolveDatabase, } from './database';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -36,6 +36,7 @@ import { SmrtObject } from "./object.js";
|
|
|
36
36
|
import { SMRT_COLLECTION_BASE_NAMES, isSmrtCollectionExtendsName } from "./registry/collection-resolution.js";
|
|
37
37
|
import { ObjectRegistry, smrt } from "./registry.js";
|
|
38
38
|
import { SmrtCollection } from "./collection.js";
|
|
39
|
+
import { executeCollectionReadPlan } from "./collection-read-plan.js";
|
|
39
40
|
import { isDatabaseInterface, resolveDatabase } from "./database.js";
|
|
40
41
|
import { crossPackageRef, field, foreignKey, manyToMany, meta, oneToMany } from "./decorators/index.js";
|
|
41
42
|
import { Dispatch } from "./dispatch/models/Dispatch.js";
|
|
@@ -73,4 +74,4 @@ import "./system/index.js";
|
|
|
73
74
|
import { getTestDatabase } from "./testing/database.js";
|
|
74
75
|
import "./tools/index.js";
|
|
75
76
|
import { smrtPlugin } from "./vite-plugin/index.js";
|
|
76
|
-
export { AIError, APIGenerator, AiUsageCollector, AiUsagePersistenceHandler, CACHE_INVALIDATION_CHANNEL, CHANGE_FEED_INTERCEPTOR_NAME, CHANGE_FEED_TABLE, CHANGE_SIGNAL_CHANNEL, CLIGenerator, ConfigurationError, ContentHasher, CosineSimilarity, DEFAULT_AI_COST_RATES, DEFAULT_CHANGES_LIMIT, DEFAULT_EMBEDDING_CONFIG, DEFAULT_EVENTS_HEARTBEAT_MS, DEFAULT_EVENTS_MAX_SUBSCRIBERS, DEFAULT_EVENTS_RETRY_AFTER_SECONDS, DEFAULT_LEARNING_CONFIG, DatabaseError, Dispatch, DispatchBus, DispatchCollection, DispatchSubscription, DispatchSubscriptionCollection, EmbeddingProvider, EmbeddingStorage, ErrorUtils, FilesystemError, GlobalInterceptors, LearningMemory, MAX_CHANGES_LIMIT, MAX_SYNC_APPLY_BATCH_SIZE, MCPGenerator, MCP_STABLE_CATALOG_TTL_MS, MODULE_DOC_HASH_PREFIX, ManifestBuilder, ManifestGenerator, ManifestManager, MetricsAdapter, NetworkError, ObjectRegistry, PRIVATE_READ_CACHE_CONTROL, PubSubAdapter, RuntimeError, SMRT_COLLECTION_BASE_NAMES, SMRT_CUSTOM_ACTION_ERROR_METADATA_KEY, SYNC_APPLY_ROUTE_SEGMENTS, SYNC_APPLY_UUID_PATTERN, SchemaComparer, SignalBus, SignalSanitizer, SmrtClass, SmrtCollection, SmrtError, SmrtHierarchical, SmrtJunction, SmrtMCPServer, SmrtObject, SmrtPolymorphicAssociation, TenantIsolationError, ValidationError, ValidationReport, ValidationUtils, appendChange, applyOneToManyChildAccessors, applyPendingDecoratorRegistrations, applySyncWritablePolicy, assertPostgresSystemTimestampsCurrent, broadcastCacheInvalidation, buildChangeEventStream, buildCustomActionInputSchema, buildCustomActionInvocationArgs, buildDomainKnowledgeManifest, bumpChangeFeed, canonicalReadRepresentation, changeEventSubscribersAtCapacity, childAccessorName, clone, computeBodyEtag, computeRuntimeWebManifestHash, computeTableVersionEtag, conditionalJsonResponse, config, convertTypeToJsonSchema, createDispatchBus, createFilesystemAdapter, createInterceptorContext, createMCPServer, createQualifiedName, createRestServer, createSmrtClient, createSmrtServer, crossPackageRef, customActionParameterInputName, detectEngine, discoverManifestEntry, ensureCacheInvalidationListener, ensureChangeFeedTable, ensureDispatchSubscriptionsSystemTableCompatibility, ensureDispatchSystemTableCompatibility, ensureJobEventsSystemTableCompatibility, ensureJobsSystemTableCompatibility, ensureLegacySystemTableCompatibility, estimateAiUsageCost, eventStreamCapacityExceededResponse, executeToolCall, executeToolCalls, field, findManifestEntryByQualifiedName, foreignKey, formatToolResults, generateDDLForEngine, generateOpenAPISpec, generateSchemaDiff, generateToolFromMethod, generateToolManifest, getAdapterInfo, getCLIHandler, getCacheGeneration, getChangesSince, getClassConfigResolvers, getClassName, getConfigResolver, getDatabaseEngine, getManifest, getPackageFromQualifiedName, getSQLFromDiff, getTableVersion, getTenantScopedChangesSince, getTestDatabase, hasActionableChanges, ifNoneMatchHasConcreteMatch, ifNoneMatchSatisfied, importOptionalDependency, invalidateCollectionCache, isDatabaseInterface, isFromPackage, isLazyConfigSentinel, isQualifiedName, isSmrtCollectionExtendsName, isStaleWrite, isTenantScopedClassResolved, isType, isValid, listConfigResolvers, loadExternalManifest, loadExternalManifestSync, loadLocalTestManifestSync, loadManifestFromPathSync, manifest, manyToMany, meta, migratePostgresSystemTimestamps, normalizeCustomActionFailure, normalizeEventsMaxSubscribers, normalizeTypedHttpError, oneToMany, parse, parseQualifiedName, parseSyncApplyBatch, payloadMatchesRow, planPostgresSystemTimestampMigrations, processSyncApplyBatch, pruneChangeFeed, qualifiedNamesEqual, readAgentModuleDocs, registerChangeFeedWriter, registerCompatibleFieldDecorator, registerConfigResolver, registerFilesystemAdapterFactory, registerOptionalDependency, resetChangeFeedWarnings, resetChangeSignals, resetCollectionCache, resetConfigResolvers, resetVerifiedTables, resolveAgentModuleDocPaths, resolveCustomActionMetadata, resolveDatabase, resolveDbCacheKey, resolveDispatchTenantId, resolveDispatchTenantScope, resolveLazyConfig, resolveMCPToolListCacheHint, resolveReadCacheControl, resolveTenantEtagDiscriminator, runWithTenantGate, safeParse, safeStringify, setDispatchTenantResolver, setTenantEntryPointRunner, setTenantScopedClassResolver, setupCLI, setupSwaggerUI, shouldIncludeMethod, signalVisibleToTenant, smrt, smrtPlugin, smrt as smrtRegistry, sortMCPTools, startRestServer, staticManifest, stopCacheInvalidationListeners, stopChangeSignalListeners, stringify, subscribeToChangeSignals, tableExists, tryReserveChangeEventSubscriberSlot, unregisterChangeFeedWriter, unregisterConfigResolver, validateSyncApplyItem, validateToolCall, versionConditionalResponse, warnIfSharedCacheNeutralized };
|
|
77
|
+
export { AIError, APIGenerator, AiUsageCollector, AiUsagePersistenceHandler, CACHE_INVALIDATION_CHANNEL, CHANGE_FEED_INTERCEPTOR_NAME, CHANGE_FEED_TABLE, CHANGE_SIGNAL_CHANNEL, CLIGenerator, ConfigurationError, ContentHasher, CosineSimilarity, DEFAULT_AI_COST_RATES, DEFAULT_CHANGES_LIMIT, DEFAULT_EMBEDDING_CONFIG, DEFAULT_EVENTS_HEARTBEAT_MS, DEFAULT_EVENTS_MAX_SUBSCRIBERS, DEFAULT_EVENTS_RETRY_AFTER_SECONDS, DEFAULT_LEARNING_CONFIG, DatabaseError, Dispatch, DispatchBus, DispatchCollection, DispatchSubscription, DispatchSubscriptionCollection, EmbeddingProvider, EmbeddingStorage, ErrorUtils, FilesystemError, GlobalInterceptors, LearningMemory, MAX_CHANGES_LIMIT, MAX_SYNC_APPLY_BATCH_SIZE, MCPGenerator, MCP_STABLE_CATALOG_TTL_MS, MODULE_DOC_HASH_PREFIX, ManifestBuilder, ManifestGenerator, ManifestManager, MetricsAdapter, NetworkError, ObjectRegistry, PRIVATE_READ_CACHE_CONTROL, PubSubAdapter, RuntimeError, SMRT_COLLECTION_BASE_NAMES, SMRT_CUSTOM_ACTION_ERROR_METADATA_KEY, SYNC_APPLY_ROUTE_SEGMENTS, SYNC_APPLY_UUID_PATTERN, SchemaComparer, SignalBus, SignalSanitizer, SmrtClass, SmrtCollection, SmrtError, SmrtHierarchical, SmrtJunction, SmrtMCPServer, SmrtObject, SmrtPolymorphicAssociation, TenantIsolationError, ValidationError, ValidationReport, ValidationUtils, appendChange, applyOneToManyChildAccessors, applyPendingDecoratorRegistrations, applySyncWritablePolicy, assertPostgresSystemTimestampsCurrent, broadcastCacheInvalidation, buildChangeEventStream, buildCustomActionInputSchema, buildCustomActionInvocationArgs, buildDomainKnowledgeManifest, bumpChangeFeed, canonicalReadRepresentation, changeEventSubscribersAtCapacity, childAccessorName, clone, computeBodyEtag, computeRuntimeWebManifestHash, computeTableVersionEtag, conditionalJsonResponse, config, convertTypeToJsonSchema, createDispatchBus, createFilesystemAdapter, createInterceptorContext, createMCPServer, createQualifiedName, createRestServer, createSmrtClient, createSmrtServer, crossPackageRef, customActionParameterInputName, detectEngine, discoverManifestEntry, ensureCacheInvalidationListener, ensureChangeFeedTable, ensureDispatchSubscriptionsSystemTableCompatibility, ensureDispatchSystemTableCompatibility, ensureJobEventsSystemTableCompatibility, ensureJobsSystemTableCompatibility, ensureLegacySystemTableCompatibility, estimateAiUsageCost, eventStreamCapacityExceededResponse, executeCollectionReadPlan, executeToolCall, executeToolCalls, field, findManifestEntryByQualifiedName, foreignKey, formatToolResults, generateDDLForEngine, generateOpenAPISpec, generateSchemaDiff, generateToolFromMethod, generateToolManifest, getAdapterInfo, getCLIHandler, getCacheGeneration, getChangesSince, getClassConfigResolvers, getClassName, getConfigResolver, getDatabaseEngine, getManifest, getPackageFromQualifiedName, getSQLFromDiff, getTableVersion, getTenantScopedChangesSince, getTestDatabase, hasActionableChanges, ifNoneMatchHasConcreteMatch, ifNoneMatchSatisfied, importOptionalDependency, invalidateCollectionCache, isDatabaseInterface, isFromPackage, isLazyConfigSentinel, isQualifiedName, isSmrtCollectionExtendsName, isStaleWrite, isTenantScopedClassResolved, isType, isValid, listConfigResolvers, loadExternalManifest, loadExternalManifestSync, loadLocalTestManifestSync, loadManifestFromPathSync, manifest, manyToMany, meta, migratePostgresSystemTimestamps, normalizeCustomActionFailure, normalizeEventsMaxSubscribers, normalizeTypedHttpError, oneToMany, parse, parseQualifiedName, parseSyncApplyBatch, payloadMatchesRow, planPostgresSystemTimestampMigrations, processSyncApplyBatch, pruneChangeFeed, qualifiedNamesEqual, readAgentModuleDocs, registerChangeFeedWriter, registerCompatibleFieldDecorator, registerConfigResolver, registerFilesystemAdapterFactory, registerOptionalDependency, resetChangeFeedWarnings, resetChangeSignals, resetCollectionCache, resetConfigResolvers, resetVerifiedTables, resolveAgentModuleDocPaths, resolveCustomActionMetadata, resolveDatabase, resolveDbCacheKey, resolveDispatchTenantId, resolveDispatchTenantScope, resolveLazyConfig, resolveMCPToolListCacheHint, resolveReadCacheControl, resolveTenantEtagDiscriminator, runWithTenantGate, safeParse, safeStringify, setDispatchTenantResolver, setTenantEntryPointRunner, setTenantScopedClassResolver, setupCLI, setupSwaggerUI, shouldIncludeMethod, signalVisibleToTenant, smrt, smrtPlugin, smrt as smrtRegistry, sortMCPTools, startRestServer, staticManifest, stopCacheInvalidationListeners, stopChangeSignalListeners, stringify, subscribeToChangeSignals, tableExists, tryReserveChangeEventSubscriberSlot, unregisterChangeFeedWriter, unregisterConfigResolver, validateSyncApplyItem, validateToolCall, versionConditionalResponse, warnIfSharedCacheNeutralized };
|