sqlstack 2.0.0 → 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/codegen/generateManifest.d.ts +12 -0
- package/dist/cjs/codegen/generateManifest.d.ts.map +1 -1
- package/dist/cjs/codegen/generateManifest.js +21 -11
- package/dist/cjs/codegen/generateManifest.js.map +1 -1
- package/dist/cjs/core/resolver.d.ts +25 -12
- package/dist/cjs/core/resolver.d.ts.map +1 -1
- package/dist/cjs/core/resolver.js +66 -20
- package/dist/cjs/core/resolver.js.map +1 -1
- package/dist/cjs/core/sourceScanResolver.d.ts +25 -0
- package/dist/cjs/core/sourceScanResolver.d.ts.map +1 -0
- package/dist/cjs/core/sourceScanResolver.js +56 -0
- package/dist/cjs/core/sourceScanResolver.js.map +1 -0
- package/dist/cjs/decorators/query.d.ts.map +1 -1
- package/dist/cjs/decorators/query.js +29 -16
- package/dist/cjs/decorators/query.js.map +1 -1
- package/dist/cjs/families/sqliteFamily.d.ts +26 -0
- package/dist/cjs/families/sqliteFamily.d.ts.map +1 -0
- package/dist/cjs/families/sqliteFamily.js +187 -0
- package/dist/cjs/families/sqliteFamily.js.map +1 -0
- package/dist/cjs/family.d.ts +69 -0
- package/dist/cjs/family.d.ts.map +1 -0
- package/dist/cjs/family.js +206 -0
- package/dist/cjs/family.js.map +1 -0
- package/dist/cjs/familyBinding.d.ts +22 -0
- package/dist/cjs/familyBinding.d.ts.map +1 -0
- package/dist/cjs/familyBinding.js +22 -0
- package/dist/cjs/familyBinding.js.map +1 -0
- package/dist/cjs/index.d.ts +9 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +14 -2
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/ioc.d.ts +22 -0
- package/dist/cjs/ioc.d.ts.map +1 -0
- package/dist/cjs/ioc.js +35 -0
- package/dist/cjs/ioc.js.map +1 -0
- package/dist/cjs/runtime.d.ts +25 -0
- package/dist/cjs/runtime.d.ts.map +1 -0
- package/dist/cjs/runtime.js +133 -0
- package/dist/cjs/runtime.js.map +1 -0
- package/dist/cjs/stack.d.ts +101 -0
- package/dist/cjs/stack.d.ts.map +1 -0
- package/dist/cjs/stack.js +288 -0
- package/dist/cjs/stack.js.map +1 -0
- package/dist/cjs/testing/builder.d.ts +29 -0
- package/dist/cjs/testing/builder.d.ts.map +1 -0
- package/dist/cjs/testing/builder.js +131 -0
- package/dist/cjs/testing/builder.js.map +1 -0
- package/dist/cjs/testing/index.d.ts +10 -0
- package/dist/cjs/testing/index.d.ts.map +1 -0
- package/dist/cjs/testing/index.js +18 -0
- package/dist/cjs/testing/index.js.map +1 -0
- package/dist/cjs/testing/postgres/allocator.d.ts +17 -0
- package/dist/cjs/testing/postgres/allocator.d.ts.map +1 -0
- package/dist/cjs/testing/postgres/allocator.js +54 -0
- package/dist/cjs/testing/postgres/allocator.js.map +1 -0
- package/dist/cjs/testing/postgres/database.d.ts +21 -0
- package/dist/cjs/testing/postgres/database.d.ts.map +1 -0
- package/dist/cjs/testing/postgres/database.js +39 -0
- package/dist/cjs/testing/postgres/database.js.map +1 -0
- package/dist/cjs/testing/postgres/loadData.d.ts +31 -0
- package/dist/cjs/testing/postgres/loadData.d.ts.map +1 -0
- package/dist/cjs/testing/postgres/loadData.js +184 -0
- package/dist/cjs/testing/postgres/loadData.js.map +1 -0
- package/dist/cjs/testing/postgres/server.d.ts +19 -0
- package/dist/cjs/testing/postgres/server.d.ts.map +1 -0
- package/dist/cjs/testing/postgres/server.js +78 -0
- package/dist/cjs/testing/postgres/server.js.map +1 -0
- package/dist/cjs/testing/schema/ddl.d.ts +14 -0
- package/dist/cjs/testing/schema/ddl.d.ts.map +1 -0
- package/dist/cjs/testing/schema/ddl.js +54 -0
- package/dist/cjs/testing/schema/ddl.js.map +1 -0
- package/dist/cjs/testing/schema/normalize.d.ts +7 -0
- package/dist/cjs/testing/schema/normalize.d.ts.map +1 -0
- package/dist/cjs/testing/schema/normalize.js +202 -0
- package/dist/cjs/testing/schema/normalize.js.map +1 -0
- package/dist/cjs/testing/schema/parser.d.ts +9 -0
- package/dist/cjs/testing/schema/parser.d.ts.map +1 -0
- package/dist/cjs/testing/schema/parser.js +80 -0
- package/dist/cjs/testing/schema/parser.js.map +1 -0
- package/dist/cjs/testing/schema/types.d.ts +82 -0
- package/dist/cjs/testing/schema/types.d.ts.map +1 -0
- package/dist/cjs/testing/schema/types.js +10 -0
- package/dist/cjs/testing/schema/types.js.map +1 -0
- package/dist/cjs/transactions.d.ts +14 -5
- package/dist/cjs/transactions.d.ts.map +1 -1
- package/dist/cjs/transactions.js +40 -24
- package/dist/cjs/transactions.js.map +1 -1
- package/dist/esm/codegen/generateManifest.js +20 -11
- package/dist/esm/codegen/generateManifest.js.map +1 -1
- package/dist/esm/core/resolver.js +59 -19
- package/dist/esm/core/resolver.js.map +1 -1
- package/dist/esm/core/sourceScanResolver.js +51 -0
- package/dist/esm/core/sourceScanResolver.js.map +1 -0
- package/dist/esm/decorators/query.js +31 -18
- package/dist/esm/decorators/query.js.map +1 -1
- package/dist/esm/families/sqliteFamily.js +151 -0
- package/dist/esm/families/sqliteFamily.js.map +1 -0
- package/dist/esm/family.js +202 -0
- package/dist/esm/family.js.map +1 -0
- package/dist/esm/familyBinding.js +18 -0
- package/dist/esm/familyBinding.js.map +1 -0
- package/dist/esm/index.js +8 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/ioc.js +32 -0
- package/dist/esm/ioc.js.map +1 -0
- package/dist/esm/runtime.js +94 -0
- package/dist/esm/runtime.js.map +1 -0
- package/dist/esm/stack.js +251 -0
- package/dist/esm/stack.js.map +1 -0
- package/dist/esm/testing/builder.js +95 -0
- package/dist/esm/testing/builder.js.map +1 -0
- package/dist/esm/testing/index.js +7 -0
- package/dist/esm/testing/index.js.map +1 -0
- package/dist/esm/testing/postgres/allocator.js +49 -0
- package/dist/esm/testing/postgres/allocator.js.map +1 -0
- package/dist/esm/testing/postgres/database.js +36 -0
- package/dist/esm/testing/postgres/database.js.map +1 -0
- package/dist/esm/testing/postgres/loadData.js +176 -0
- package/dist/esm/testing/postgres/loadData.js.map +1 -0
- package/dist/esm/testing/postgres/server.js +69 -0
- package/dist/esm/testing/postgres/server.js.map +1 -0
- package/dist/esm/testing/schema/ddl.js +49 -0
- package/dist/esm/testing/schema/ddl.js.map +1 -0
- package/dist/esm/testing/schema/normalize.js +164 -0
- package/dist/esm/testing/schema/normalize.js.map +1 -0
- package/dist/esm/testing/schema/parser.js +43 -0
- package/dist/esm/testing/schema/parser.js.map +1 -0
- package/dist/esm/testing/schema/types.js +9 -0
- package/dist/esm/testing/schema/types.js.map +1 -0
- package/dist/esm/transactions.js +39 -24
- package/dist/esm/transactions.js.map +1 -1
- package/package.json +18 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"family.js","sourceRoot":"","sources":["../../src/family.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Database } from './registry';\nimport { SqlStackError } from './core/errors';\nimport type { SqlStack, DatabaseEntry } from './stack';\n\n/**\n * Dynamic database families (spec 17): one registration that resolves many\n * concrete databases by key. The provider owns physical mechanics; the\n * family runtime owns identity, leases, bounded caching, and lifecycle.\n */\n\nexport interface DatabaseInspection {\n state: 'closed' | 'open' | 'missing';\n [fact: string]: unknown;\n}\n\nexport interface DatabaseFamilyProvider<K = string> {\n /** Normalize/validate an application key. Must be deterministic and safe. */\n normalizeKey(input: unknown): K;\n /** Serialize a normalized key to the identity string used for routing. */\n keyId?(key: K): string;\n /** Open an EXISTING database. Must fail if it does not exist (never create). */\n open(key: K): Promise<Database>;\n /** Create a NEW database. Must fail if it already exists. */\n create?(key: K): Promise<Database>;\n /** Explicit create-if-missing. */\n ensure?(key: K): Promise<Database>;\n exists?(key: K): Promise<boolean>;\n /** Physically delete the database (handle already closed by the runtime). */\n delete?(key: K): Promise<void>;\n inspect?(key: K): Promise<DatabaseInspection>;\n list?(): AsyncIterable<K>;\n}\n\nexport interface FamilyConfig<K = string> {\n provider: DatabaseFamilyProvider<K>;\n cache?: {\n /** Max concurrently open members (default 16). Leased members never evict. */\n maxOpen?: number;\n };\n}\n\n/** Concrete member identity: owning stack + family registration + key. */\nexport interface FamilyMemberEntry extends DatabaseEntry {\n readonly family: string;\n readonly keyId: string;\n}\n\nexport interface DatabaseLease {\n readonly entry: FamilyMemberEntry;\n release(): Promise<void>;\n}\n\ntype MemberState = {\n entry: FamilyMemberEntry;\n db?: Database;\n opening?: Promise<Database>;\n leases: number;\n lastUsed: number;\n};\n\nfunction unsupported(family: string, op: string): never {\n throw new SqlStackError(\n `Database family \"${family}\" does not support ${op}(): its provider declares no such capability.`\n );\n}\n\nexport class FamilyRuntime<K = string> {\n readonly name: string;\n readonly #stack: SqlStack;\n readonly #provider: DatabaseFamilyProvider<K>;\n readonly #maxOpen: number;\n readonly #members = new Map<string, MemberState>();\n #useTick = 0;\n #closed = false;\n\n constructor(stack: SqlStack, name: string, config: FamilyConfig<K>) {\n this.#stack = stack;\n this.name = name;\n this.#provider = config.provider;\n this.#maxOpen = config.cache?.maxOpen ?? 16;\n }\n\n normalize(input: unknown): { key: K; keyId: string } {\n const key = this.#provider.normalizeKey(input);\n const keyId = this.#provider.keyId ? this.#provider.keyId(key) : String(key);\n return { key, keyId };\n }\n\n /** Stable concrete identity for a key; no I/O. */\n ref(input: unknown): FamilyMemberEntry {\n return this.#member(input).entry;\n }\n\n async exists(input: unknown): Promise<boolean> {\n const { key } = this.normalize(input);\n if (!this.#provider.exists) unsupported(this.name, 'exists');\n return this.#provider.exists(key);\n }\n\n async create(input: unknown): Promise<void> {\n this.#assertOpen();\n const member = this.#member(input);\n if (!this.#provider.create) unsupported(this.name, 'create');\n const db = await this.#provider.create(member.key);\n await db.close();\n }\n\n async ensure(input: unknown): Promise<void> {\n this.#assertOpen();\n const member = this.#member(input);\n if (!this.#provider.ensure) unsupported(this.name, 'ensure');\n const db = await this.#provider.ensure(member.key);\n await db.close();\n }\n\n /** Acquire a lease on an opened (existing) member. */\n async acquire(input: unknown): Promise<DatabaseLease> {\n this.#assertOpen();\n const member = this.#member(input);\n await this.#open(member);\n member.leases++;\n member.lastUsed = ++this.#useTick;\n let released = false;\n return {\n entry: member.entry,\n release: async () => {\n if (released) return;\n released = true;\n member.leases = Math.max(0, member.leases - 1);\n this.#evictIfNeeded();\n },\n };\n }\n\n async with<T>(input: unknown, fn: (entry: FamilyMemberEntry) => Promise<T>): Promise<T> {\n const lease = await this.acquire(input);\n try {\n return await fn(lease.entry);\n } finally {\n await lease.release();\n }\n }\n\n /** Close/evict a member's cached handle; the database itself is preserved. */\n async closeMember(input: unknown): Promise<void> {\n const { keyId } = this.normalize(input);\n const member = this.#members.get(keyId);\n if (!member?.db) return;\n if (member.leases > 0) {\n throw new SqlStackError(\n `Cannot close \"${this.name}/${keyId}\": ${member.leases} lease(s) are active.`\n );\n }\n await this.#closeHandle(member);\n }\n\n /** Physically delete a member. Fails while leased; closes the cached handle first. */\n async deleteMember(input: unknown): Promise<void> {\n this.#assertOpen();\n const member = this.#member(input);\n if (!this.#provider.delete) unsupported(this.name, 'delete');\n if (member.leases > 0) {\n throw new SqlStackError(\n `Cannot delete \"${this.name}/${member.entry.keyId}\": ${member.leases} lease(s) are active.`\n );\n }\n if (member.db) await this.#closeHandle(member);\n await this.#provider.delete(member.key);\n this.#members.delete(member.entry.keyId);\n }\n\n async inspect(input: unknown): Promise<DatabaseInspection> {\n const member = this.#member(input);\n if (!this.#provider.inspect) unsupported(this.name, 'inspect');\n const facts = await this.#provider.inspect(member.key);\n return { ...facts, cached: !!member.db, activeLeases: member.leases };\n }\n\n /** Close every cached handle (root disposal). Databases are preserved. */\n async closeAll(): Promise<void> {\n this.#closed = true;\n const failures: string[] = [];\n for (const member of this.#members.values()) {\n if (!member.db) continue;\n try {\n await this.#closeHandle(member);\n } catch (err: any) {\n failures.push(`\"${this.name}/${member.entry.keyId}\": ${err?.message ?? String(err)}`);\n }\n }\n this.#members.clear();\n if (failures.length) {\n throw new SqlStackError(`Family close failed for ${failures.join(', ')}`);\n }\n }\n\n #member(input: unknown): MemberState & { key: K } {\n const { key, keyId } = this.normalize(input);\n let member = this.#members.get(keyId);\n if (!member) {\n const self = this;\n const entry: FamilyMemberEntry = {\n name: this.name,\n family: this.name,\n keyId,\n owned: true,\n stack: this.#stack,\n get db(): Database {\n const state = self.#members.get(keyId);\n if (!state?.db) {\n throw new SqlStackError(\n `Database family member \"${self.name}/${keyId}\" is not open. ` +\n 'Acquire it through withDatabase(...)/family.with(...) before querying.'\n );\n }\n return state.db;\n },\n };\n member = { entry, leases: 0, lastUsed: 0 };\n this.#members.set(keyId, member);\n }\n return Object.assign(member, { key: this.normalize(input).key });\n }\n\n async #open(member: MemberState & { key: K }): Promise<void> {\n if (member.db) return;\n if (!member.opening) {\n member.opening = this.#provider.open(member.key).finally(() => {\n member.opening = undefined;\n });\n member.opening.catch(() => undefined); // surfaced to awaiting callers\n }\n const db = await member.opening;\n member.db = db;\n this.#evictIfNeeded();\n }\n\n async #closeHandle(member: MemberState): Promise<void> {\n const db = member.db;\n member.db = undefined;\n if (db) await db.close();\n }\n\n #evictIfNeeded(): void {\n const open = [...this.#members.values()].filter((m) => m.db);\n if (open.length <= this.#maxOpen) return;\n const evictable = open\n .filter((m) => m.leases === 0)\n .sort((a, b) => a.lastUsed - b.lastUsed);\n for (const member of evictable) {\n if ([...this.#members.values()].filter((m) => m.db).length <= this.#maxOpen) break;\n // Fire-and-forget close; eviction failures must not break the acquiring flow.\n void this.#closeHandle(member).catch(() => undefined);\n }\n }\n\n #assertOpen(): void {\n if (this.#closed) {\n throw new SqlStackError(`Database family \"${this.name}\" belongs to a closed SqlStack.`);\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { AsyncLocalStorage } from 'node:async_hooks';
|
|
2
|
+
const als = new AsyncLocalStorage();
|
|
3
|
+
export function currentBinding(stack, family) {
|
|
4
|
+
const frames = als.getStore();
|
|
5
|
+
if (!frames)
|
|
6
|
+
return undefined;
|
|
7
|
+
for (let i = frames.length - 1; i >= 0; i--) {
|
|
8
|
+
const frame = frames[i];
|
|
9
|
+
if (frame.stack === stack && frame.family === family)
|
|
10
|
+
return frame;
|
|
11
|
+
}
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
export function runWithBinding(frame, fn) {
|
|
15
|
+
const frames = als.getStore() ?? [];
|
|
16
|
+
return als.run([...frames, frame], fn);
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=familyBinding.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"familyBinding.js","sourceRoot":"","sources":["../../src/familyBinding.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAsBrD,MAAM,GAAG,GAAG,IAAI,iBAAiB,EAA2B,CAAC;AAE7D,MAAM,UAAU,cAAc,CAAC,KAAe,EAAE,MAAc;IAC5D,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC;IAC9B,IAAI,CAAC,MAAM;QAAE,OAAO,SAAS,CAAC;IAC9B,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC5C,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;QACxB,IAAI,KAAK,CAAC,KAAK,KAAK,KAAK,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM;YAAE,OAAO,KAAK,CAAC;IACrE,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,cAAc,CAAI,KAAmB,EAAE,EAAW;IAChE,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC;IACpC,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;AACzC,CAAC","sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks';\nimport type { SqlStack } from './stack';\nimport type { DatabaseLease } from './family';\n\n/**\n * SQLStack-owned flow-local family binding (spec 17 §10-11).\n *\n * This carries WHICH concrete member of a dynamic family is selected for the\n * current execution flow. It is deliberately separate from the IoC execution\n * context (which owns root identity) and from transaction state. Frames are\n * keyed by SqlStack instance, so two roots binding the same family name can\n * never observe each other's selection.\n */\nexport type BindingFrame = {\n readonly stack: SqlStack;\n readonly family: string;\n readonly keyInput: unknown;\n readonly keyId: string;\n /** Acquired lazily on first database resolution inside the frame. */\n lease?: DatabaseLease;\n};\n\nconst als = new AsyncLocalStorage<readonly BindingFrame[]>();\n\nexport function currentBinding(stack: SqlStack, family: string): BindingFrame | undefined {\n const frames = als.getStore();\n if (!frames) return undefined;\n for (let i = frames.length - 1; i >= 0; i--) {\n const frame = frames[i];\n if (frame.stack === stack && frame.family === family) return frame;\n }\n return undefined;\n}\n\nexport function runWithBinding<T>(frame: BindingFrame, fn: () => T): T {\n const frames = als.getStore() ?? [];\n return als.run([...frames, frame], fn);\n}\n"]}
|
package/dist/esm/index.js
CHANGED
|
@@ -18,7 +18,14 @@ export * from './core/validator.js';
|
|
|
18
18
|
// DTO Helper
|
|
19
19
|
export * from './utils/dto.js';
|
|
20
20
|
export { SqlStackDB } from './registry.js';
|
|
21
|
-
|
|
21
|
+
// Environment-owned runtime (v3): per-root SqlStack + active-context resolution
|
|
22
|
+
export { SqlStack } from './stack.js';
|
|
23
|
+
export { activeSqlStack, resolveExecution } from './runtime.js';
|
|
24
|
+
// Dynamic database families (spec 17)
|
|
25
|
+
export { FamilyRuntime } from './family.js';
|
|
26
|
+
export { sqliteFamily } from './families/sqliteFamily.js';
|
|
27
|
+
export { FsResolver, ManifestResolver, MANIFEST_DIALECT_EXT } from './core/resolver.js';
|
|
28
|
+
export { SourceScanResolver } from './core/sourceScanResolver.js';
|
|
22
29
|
// Legacy exports (kept for backward compatibility)
|
|
23
30
|
export * from './binders/sqlBinder.js';
|
|
24
31
|
//# sourceMappingURL=index.js.map
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,uBAAuB;AACvB,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAEzC,aAAa;AACb,cAAc,0BAA0B,CAAC;AACzC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAElC,eAAe;AACf,cAAc,gBAAgB,CAAC;AAE/B,WAAW;AACX,cAAc,YAAY,CAAC;AAE3B,wBAAwB;AACxB,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AAEjC,aAAa;AACb,cAAc,aAAa,CAAC;AAI5B,OAAO,EAAE,UAAU,EAAY,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,uBAAuB;AACvB,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAEzC,aAAa;AACb,cAAc,0BAA0B,CAAC;AACzC,cAAc,oBAAoB,CAAC;AACnC,cAAc,uBAAuB,CAAC;AACtC,cAAc,0BAA0B,CAAC;AACzC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAElC,eAAe;AACf,cAAc,gBAAgB,CAAC;AAE/B,WAAW;AACX,cAAc,YAAY,CAAC;AAE3B,wBAAwB;AACxB,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AAEjC,aAAa;AACb,cAAc,aAAa,CAAC;AAI5B,OAAO,EAAE,UAAU,EAAY,MAAM,YAAY,CAAC;AAElD,gFAAgF;AAChF,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAEnC,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAE7D,sCAAsC;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAQzC,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAKvD,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACrF,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D,mDAAmD;AACnD,cAAc,qBAAqB,CAAC","sourcesContent":["// SQL Template Strings\nexport { sql, SqlFragment } from './sql';\n\n// Decorators\nexport * from './decorators/queryBinder';\nexport * from './decorators/query';\nexport * from './decorators/defaults';\nexport * from './decorators/resultShape';\nexport * from './decorators/validateResult';\nexport * from './decorators/transform';\nexport * from './decorators/page';\n\n// Transactions\nexport * from './transactions';\n\n// Adapters\nexport * from './adapters';\n\n// Errors and Validation\nexport * from './core/errors';\nexport * from './core/validator';\n\n// DTO Helper\nexport * from './utils/dto';\n\n// Database Registry and Types\nexport type { Dialect, WriteResult, PostgresWriteResult, QueryResult, Database } from './registry';\nexport { SqlStackDB, IStackDB } from './registry';\n\n// Environment-owned runtime (v3): per-root SqlStack + active-context resolution\nexport { SqlStack } from './stack';\nexport type { DatabaseEntry, DatabaseRegistration, SqlStackConfig } from './stack';\nexport { activeSqlStack, resolveExecution } from './runtime';\n\n// Dynamic database families (spec 17)\nexport { FamilyRuntime } from './family';\nexport type {\n DatabaseFamilyProvider,\n FamilyConfig,\n FamilyMemberEntry,\n DatabaseLease,\n DatabaseInspection,\n} from './family';\nexport { sqliteFamily } from './families/sqliteFamily';\nexport type { SqliteFamilyOptions } from './families/sqliteFamily';\n\n// SQL Resolvers (v2): pluggable SQL source resolution\nexport type { SqlResolver, SqlManifest, SqlResolutionRequest, ManifestResolverOptions } from './core/resolver';\nexport { FsResolver, ManifestResolver, MANIFEST_DIALECT_EXT } from './core/resolver';\nexport { SourceScanResolver } from './core/sourceScanResolver';\n\n// Legacy exports (kept for backward compatibility)\nexport * from './binders/sqlBinder';\n"]}
|
package/dist/esm/ioc.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { LoadAs } from '@noego/ioc';
|
|
2
|
+
import { SqlStack } from './stack.js';
|
|
3
|
+
/**
|
|
4
|
+
* Root composition for SQLStack (repo spec 19 §6).
|
|
5
|
+
*
|
|
6
|
+
* Registers a per-root SqlStack Singleton built from normalized application
|
|
7
|
+
* configuration. Different roots in one process may register different
|
|
8
|
+
* database URLs/resolvers concurrently; child scopes resolve the owning
|
|
9
|
+
* root's instance under normal IoC semantics.
|
|
10
|
+
*
|
|
11
|
+
* This module is the only sqlstack module that imports @noego/ioc statically;
|
|
12
|
+
* core query execution reaches the active root through the IoC execution
|
|
13
|
+
* context without a hard dependency.
|
|
14
|
+
*
|
|
15
|
+
* Lifecycle: the returned dispose function closes SqlStack-owned database
|
|
16
|
+
* adapters. Call it when disposing the root (or wire it into the root's
|
|
17
|
+
* disposal hook where the container version supports one).
|
|
18
|
+
*/
|
|
19
|
+
export function registerSqlStack(container, config) {
|
|
20
|
+
let instance;
|
|
21
|
+
container.registerFunction(SqlStack, () => {
|
|
22
|
+
instance = new SqlStack(typeof config === 'function' ? config() : config);
|
|
23
|
+
return instance;
|
|
24
|
+
}, { loadAs: LoadAs.Singleton });
|
|
25
|
+
return {
|
|
26
|
+
dispose: async () => {
|
|
27
|
+
if (instance)
|
|
28
|
+
await instance.close();
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=ioc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ioc.js","sourceRoot":"","sources":["../../src/ioc.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAEpC,OAAO,EAAE,QAAQ,EAAkB,MAAM,SAAS,CAAC;AAEnD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,gBAAgB,CAC9B,SAA0B,EAC1B,MAA+C;IAE/C,IAAI,QAA8B,CAAC;IAClC,SAAiB,CAAC,gBAAgB,CACjC,QAAQ,EACR,GAAG,EAAE;QACH,QAAQ,GAAG,IAAI,QAAQ,CAAC,OAAO,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAC1E,OAAO,QAAQ,CAAC;IAClB,CAAC,EACD,EAAE,MAAM,EAAE,MAAM,CAAC,SAAS,EAAE,CAC7B,CAAC;IACF,OAAO;QACL,OAAO,EAAE,KAAK,IAAI,EAAE;YAClB,IAAI,QAAQ;gBAAE,MAAM,QAAQ,CAAC,KAAK,EAAE,CAAC;QACvC,CAAC;KACF,CAAC;AACJ,CAAC","sourcesContent":["import { LoadAs } from '@noego/ioc';\nimport type { IContainerSetup } from '@noego/ioc';\nimport { SqlStack, SqlStackConfig } from './stack';\n\n/**\n * Root composition for SQLStack (repo spec 19 §6).\n *\n * Registers a per-root SqlStack Singleton built from normalized application\n * configuration. Different roots in one process may register different\n * database URLs/resolvers concurrently; child scopes resolve the owning\n * root's instance under normal IoC semantics.\n *\n * This module is the only sqlstack module that imports @noego/ioc statically;\n * core query execution reaches the active root through the IoC execution\n * context without a hard dependency.\n *\n * Lifecycle: the returned dispose function closes SqlStack-owned database\n * adapters. Call it when disposing the root (or wire it into the root's\n * disposal hook where the container version supports one).\n */\nexport function registerSqlStack(\n container: IContainerSetup,\n config: SqlStackConfig | (() => SqlStackConfig)\n): { dispose: () => Promise<void> } {\n let instance: SqlStack | undefined;\n (container as any).registerFunction(\n SqlStack,\n () => {\n instance = new SqlStack(typeof config === 'function' ? config() : config);\n return instance;\n },\n { loadAs: LoadAs.Singleton }\n );\n return {\n dispose: async () => {\n if (instance) await instance.close();\n },\n };\n}\n"]}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { SqlStack } from './stack.js';
|
|
2
|
+
import { SqlStackDB } from './registry.js';
|
|
3
|
+
import { getActiveResolver } from './core/resolver.js';
|
|
4
|
+
import { SqlStackError } from './core/errors.js';
|
|
5
|
+
// @noego/ioc is an optional peer: sqlstack remains usable standalone. The
|
|
6
|
+
// import is dynamic so the CJS and ESM builds both work and so a missing
|
|
7
|
+
// peer only disables the IoC path instead of breaking module load.
|
|
8
|
+
let iocModulePromise;
|
|
9
|
+
function loadIoc() {
|
|
10
|
+
iocModulePromise ?? (iocModulePromise = import('@noego/ioc').then((m) => (m?.ExecutionContext ? m : undefined), () => undefined));
|
|
11
|
+
return iocModulePromise;
|
|
12
|
+
}
|
|
13
|
+
/** @internal Test-only: force re-detection of @noego/ioc. */
|
|
14
|
+
export function __resetIocDetection() {
|
|
15
|
+
iocModulePromise = undefined;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* The SqlStack for the active IoC execution context, or undefined when no
|
|
19
|
+
* IoC environment is active (or @noego/ioc is not installed).
|
|
20
|
+
*
|
|
21
|
+
* Throws when an environment IS active but has no SqlStack registered —
|
|
22
|
+
* silently falling back to global state under an active root is forbidden.
|
|
23
|
+
*/
|
|
24
|
+
export async function activeSqlStack() {
|
|
25
|
+
const ioc = await loadIoc();
|
|
26
|
+
if (!ioc)
|
|
27
|
+
return undefined;
|
|
28
|
+
const scope = ioc.ExecutionContext.current();
|
|
29
|
+
if (!scope)
|
|
30
|
+
return undefined;
|
|
31
|
+
try {
|
|
32
|
+
return (await scope.get(SqlStack));
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
if (err?.constructor?.name === 'DependencyNotFoundError') {
|
|
36
|
+
// Migration compatibility: a root with NO SqlStack registered may fall
|
|
37
|
+
// back to the deprecated global registry — that is not legacy state
|
|
38
|
+
// overriding a configured root, because the root configured nothing.
|
|
39
|
+
// A root that HAS a SqlStack is always authoritative.
|
|
40
|
+
if (hasLegacyDefault())
|
|
41
|
+
return undefined;
|
|
42
|
+
throw new SqlStackError('An IoC execution environment is active, but no SqlStack is registered in it ' +
|
|
43
|
+
'and no legacy SqlStackDB default exists. Register a SqlStack at root ' +
|
|
44
|
+
'composition (see registerSqlStack in "sqlstack/ioc").');
|
|
45
|
+
}
|
|
46
|
+
throw err;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Resolve the concrete database entry (and SQL resolver) for one execution.
|
|
51
|
+
*/
|
|
52
|
+
export async function resolveExecution(dbName) {
|
|
53
|
+
const stack = await activeSqlStack();
|
|
54
|
+
if (stack) {
|
|
55
|
+
return { entry: await stack.resolveEntry(dbName), resolver: stack.resolver(), viaStack: true };
|
|
56
|
+
}
|
|
57
|
+
return {
|
|
58
|
+
entry: legacyEntry(dbName),
|
|
59
|
+
resolver: getActiveResolver(),
|
|
60
|
+
viaStack: false,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
// ---------------------------------------------------------------------------
|
|
64
|
+
// Legacy (deprecated) global-registry support
|
|
65
|
+
// ---------------------------------------------------------------------------
|
|
66
|
+
// Stable DatabaseEntry identities for the legacy global registry, so the
|
|
67
|
+
// entry-keyed transaction store works identically on both paths. Keyed by
|
|
68
|
+
// name AND database object so re-registration under a name yields a fresh
|
|
69
|
+
// identity (matching the fresh underlying connection).
|
|
70
|
+
const legacyEntries = new Map();
|
|
71
|
+
// One shared legacy pseudo-stack so legacy entries carry a stack identity for
|
|
72
|
+
// diagnostics. It is intentionally NOT usable as a real stack.
|
|
73
|
+
let legacyStack;
|
|
74
|
+
function hasLegacyDefault() {
|
|
75
|
+
try {
|
|
76
|
+
SqlStackDB.getEntry();
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
return false;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/** @internal Resolve a legacy global-registry database as a DatabaseEntry. */
|
|
84
|
+
export function legacyEntry(dbName) {
|
|
85
|
+
const { name, db } = SqlStackDB.getEntry(dbName);
|
|
86
|
+
const cached = legacyEntries.get(name);
|
|
87
|
+
if (cached && cached.db === db)
|
|
88
|
+
return cached.entry;
|
|
89
|
+
legacyStack ?? (legacyStack = new SqlStack());
|
|
90
|
+
const entry = { name, db, owned: false, stack: legacyStack };
|
|
91
|
+
legacyEntries.set(name, { db, entry });
|
|
92
|
+
return entry;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=runtime.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/runtime.ts"],"names":[],"mappings":"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","sourcesContent":["import { SqlStack, DatabaseEntry } from './stack';\nimport { SqlStackDB } from './registry';\nimport type { Database } from './registry';\nimport type { SqlResolver } from './core/resolver';\nimport { getActiveResolver } from './core/resolver';\nimport { SqlStackError } from './core/errors';\n\n/**\n * Active-environment resolution for @Query and transactions (spec 16 §17,\n * repo spec 19 §7/§9).\n *\n * Canonical path: the active IoC execution context (owned by @noego/ioc)\n * supplies the current scope; the scope resolves its root's SqlStack\n * Singleton. When an IoC environment is active, the process-global legacy\n * registry is NEVER consulted — legacy state cannot override an active root.\n *\n * Legacy path: with no active IoC environment, execution falls back to the\n * deprecated process-global SqlStackDB registry so existing consumers keep\n * working during migration.\n */\n\ntype IocModule = {\n ExecutionContext: { current(): any };\n};\n\n// @noego/ioc is an optional peer: sqlstack remains usable standalone. The\n// import is dynamic so the CJS and ESM builds both work and so a missing\n// peer only disables the IoC path instead of breaking module load.\nlet iocModulePromise: Promise<IocModule | undefined> | undefined;\n\nfunction loadIoc(): Promise<IocModule | undefined> {\n iocModulePromise ??= import('@noego/ioc').then(\n (m: any) => (m?.ExecutionContext ? (m as IocModule) : undefined),\n () => undefined\n );\n return iocModulePromise;\n}\n\n/** @internal Test-only: force re-detection of @noego/ioc. */\nexport function __resetIocDetection(): void {\n iocModulePromise = undefined;\n}\n\n/**\n * The SqlStack for the active IoC execution context, or undefined when no\n * IoC environment is active (or @noego/ioc is not installed).\n *\n * Throws when an environment IS active but has no SqlStack registered —\n * silently falling back to global state under an active root is forbidden.\n */\nexport async function activeSqlStack(): Promise<SqlStack | undefined> {\n const ioc = await loadIoc();\n if (!ioc) return undefined;\n const scope = ioc.ExecutionContext.current();\n if (!scope) return undefined;\n try {\n return (await scope.get(SqlStack)) as SqlStack;\n } catch (err: any) {\n if (err?.constructor?.name === 'DependencyNotFoundError') {\n // Migration compatibility: a root with NO SqlStack registered may fall\n // back to the deprecated global registry — that is not legacy state\n // overriding a configured root, because the root configured nothing.\n // A root that HAS a SqlStack is always authoritative.\n if (hasLegacyDefault()) return undefined;\n throw new SqlStackError(\n 'An IoC execution environment is active, but no SqlStack is registered in it ' +\n 'and no legacy SqlStackDB default exists. Register a SqlStack at root ' +\n 'composition (see registerSqlStack in \"sqlstack/ioc\").'\n );\n }\n throw err;\n }\n}\n\nexport type ResolvedExecution = {\n entry: DatabaseEntry;\n resolver: SqlResolver | undefined;\n /** True when resolved through an active IoC root's SqlStack. */\n viaStack: boolean;\n};\n\n/**\n * Resolve the concrete database entry (and SQL resolver) for one execution.\n */\nexport async function resolveExecution(dbName?: string): Promise<ResolvedExecution> {\n const stack = await activeSqlStack();\n if (stack) {\n return { entry: await stack.resolveEntry(dbName), resolver: stack.resolver(), viaStack: true };\n }\n return {\n entry: legacyEntry(dbName),\n resolver: getActiveResolver(),\n viaStack: false,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Legacy (deprecated) global-registry support\n// ---------------------------------------------------------------------------\n\n// Stable DatabaseEntry identities for the legacy global registry, so the\n// entry-keyed transaction store works identically on both paths. Keyed by\n// name AND database object so re-registration under a name yields a fresh\n// identity (matching the fresh underlying connection).\nconst legacyEntries = new Map<string, { db: Database; entry: DatabaseEntry }>();\n\n// One shared legacy pseudo-stack so legacy entries carry a stack identity for\n// diagnostics. It is intentionally NOT usable as a real stack.\nlet legacyStack: SqlStack | undefined;\n\nfunction hasLegacyDefault(): boolean {\n try {\n SqlStackDB.getEntry();\n return true;\n } catch {\n return false;\n }\n}\n\n/** @internal Resolve a legacy global-registry database as a DatabaseEntry. */\nexport function legacyEntry(dbName?: string): DatabaseEntry {\n const { name, db } = SqlStackDB.getEntry(dbName);\n const cached = legacyEntries.get(name);\n if (cached && cached.db === db) return cached.entry;\n legacyStack ??= new SqlStack();\n const entry: DatabaseEntry = { name, db, owned: false, stack: legacyStack };\n legacyEntries.set(name, { db, entry });\n return entry;\n}\n"]}
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
2
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
3
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
4
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
|
+
};
|
|
6
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
7
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
10
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
11
|
+
};
|
|
12
|
+
var _SqlStack_instances, _SqlStack_entries, _SqlStack_families, _SqlStack_defaultName, _SqlStack_resolver, _SqlStack_closed, _SqlStack_assertOpen, _SqlStack_registeredNames;
|
|
13
|
+
import { setGlobalResolver, clearGlobalResolver, ManifestResolver, assertManifestCoverage, assertManifestCoversClasses, } from './core/resolver.js';
|
|
14
|
+
import { SqlStackError } from './core/errors.js';
|
|
15
|
+
import { FamilyRuntime } from './family.js';
|
|
16
|
+
import { currentBinding, runWithBinding } from './familyBinding.js';
|
|
17
|
+
/**
|
|
18
|
+
* Environment-owned SQLStack runtime (spec 16 §12-13, repo spec 19 §3-5).
|
|
19
|
+
*
|
|
20
|
+
* One instance per owning IoC root; child scopes resolve the root's Singleton.
|
|
21
|
+
* Native @Query/transaction/resolver execution goes through an instance —
|
|
22
|
+
* never through the process-global SqlStackDB registry.
|
|
23
|
+
*/
|
|
24
|
+
export class SqlStack {
|
|
25
|
+
/**
|
|
26
|
+
* @deprecated Legacy v2 process-global resolver registration
|
|
27
|
+
* (`SqlStack.useResolver(...)`). Forwards to the deprecated global state,
|
|
28
|
+
* which is only consulted when no IoC environment is active. Use the
|
|
29
|
+
* per-instance `useResolver` / SqlStackConfig.resolver instead.
|
|
30
|
+
*/
|
|
31
|
+
static useResolver(resolver) {
|
|
32
|
+
setGlobalResolver(resolver);
|
|
33
|
+
}
|
|
34
|
+
/** @deprecated See static useResolver. */
|
|
35
|
+
static clearResolver() {
|
|
36
|
+
clearGlobalResolver();
|
|
37
|
+
}
|
|
38
|
+
constructor(config) {
|
|
39
|
+
_SqlStack_instances.add(this);
|
|
40
|
+
_SqlStack_entries.set(this, new Map());
|
|
41
|
+
_SqlStack_families.set(this, new Map());
|
|
42
|
+
_SqlStack_defaultName.set(this, void 0);
|
|
43
|
+
_SqlStack_resolver.set(this, void 0);
|
|
44
|
+
_SqlStack_closed.set(this, false);
|
|
45
|
+
if (config?.databases) {
|
|
46
|
+
for (const [name, reg] of Object.entries(config.databases)) {
|
|
47
|
+
if (typeof reg === 'object' && reg !== null && 'db' in reg) {
|
|
48
|
+
const db = typeof reg.db === 'function' ? reg.db() : reg.db;
|
|
49
|
+
this.register(name, db, { owned: reg.owned ?? typeof reg.db === 'function' });
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
this.register(name, reg);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (config?.default)
|
|
57
|
+
this.setDefault(config.default);
|
|
58
|
+
if (config?.resolver)
|
|
59
|
+
this.useResolver(config.resolver);
|
|
60
|
+
}
|
|
61
|
+
register(name, db, options) {
|
|
62
|
+
__classPrivateFieldGet(this, _SqlStack_instances, "m", _SqlStack_assertOpen).call(this);
|
|
63
|
+
const entry = { name, db, owned: options?.owned ?? false, stack: this };
|
|
64
|
+
__classPrivateFieldGet(this, _SqlStack_entries, "f").set(name, entry);
|
|
65
|
+
if (options?.default || __classPrivateFieldGet(this, _SqlStack_entries, "f").size === 1) {
|
|
66
|
+
__classPrivateFieldSet(this, _SqlStack_defaultName, __classPrivateFieldGet(this, _SqlStack_defaultName, "f") ?? name, "f");
|
|
67
|
+
if (options?.default)
|
|
68
|
+
__classPrivateFieldSet(this, _SqlStack_defaultName, name, "f");
|
|
69
|
+
}
|
|
70
|
+
return this;
|
|
71
|
+
}
|
|
72
|
+
setDefault(name) {
|
|
73
|
+
__classPrivateFieldGet(this, _SqlStack_instances, "m", _SqlStack_assertOpen).call(this);
|
|
74
|
+
if (!__classPrivateFieldGet(this, _SqlStack_entries, "f").has(name)) {
|
|
75
|
+
throw new SqlStackError(`SqlStack has no database registered under "${name}". Registered: ${__classPrivateFieldGet(this, _SqlStack_instances, "m", _SqlStack_registeredNames).call(this)}`);
|
|
76
|
+
}
|
|
77
|
+
__classPrivateFieldSet(this, _SqlStack_defaultName, name, "f");
|
|
78
|
+
return this;
|
|
79
|
+
}
|
|
80
|
+
getEntry(name) {
|
|
81
|
+
__classPrivateFieldGet(this, _SqlStack_instances, "m", _SqlStack_assertOpen).call(this);
|
|
82
|
+
const key = name ?? __classPrivateFieldGet(this, _SqlStack_defaultName, "f");
|
|
83
|
+
if (!key) {
|
|
84
|
+
throw new SqlStackError('SqlStack has no default database. Register one with { default: true } or call setDefault(name).');
|
|
85
|
+
}
|
|
86
|
+
const entry = __classPrivateFieldGet(this, _SqlStack_entries, "f").get(key);
|
|
87
|
+
if (!entry) {
|
|
88
|
+
throw new SqlStackError(`SqlStack has no database registered under "${key}". Registered: ${__classPrivateFieldGet(this, _SqlStack_instances, "m", _SqlStack_registeredNames).call(this)}`);
|
|
89
|
+
}
|
|
90
|
+
return entry;
|
|
91
|
+
}
|
|
92
|
+
database(name) {
|
|
93
|
+
return this.getEntry(name).db;
|
|
94
|
+
}
|
|
95
|
+
has(name) {
|
|
96
|
+
return __classPrivateFieldGet(this, _SqlStack_entries, "f").has(name) || __classPrivateFieldGet(this, _SqlStack_families, "f").has(name);
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Register a dynamic database family (spec 17): one registration whose
|
|
100
|
+
* concrete member is selected per execution flow via withDatabase(...).
|
|
101
|
+
*/
|
|
102
|
+
registerFamily(name, config) {
|
|
103
|
+
__classPrivateFieldGet(this, _SqlStack_instances, "m", _SqlStack_assertOpen).call(this);
|
|
104
|
+
if (__classPrivateFieldGet(this, _SqlStack_entries, "f").has(name)) {
|
|
105
|
+
throw new SqlStackError(`"${name}" is already registered as a static database.`);
|
|
106
|
+
}
|
|
107
|
+
__classPrivateFieldGet(this, _SqlStack_families, "f").set(name, new FamilyRuntime(this, name, config));
|
|
108
|
+
return this;
|
|
109
|
+
}
|
|
110
|
+
family(name) {
|
|
111
|
+
const fam = __classPrivateFieldGet(this, _SqlStack_families, "f").get(name);
|
|
112
|
+
if (!fam) {
|
|
113
|
+
throw new SqlStackError(`SqlStack has no database family registered under "${name}". Families: ${[...__classPrivateFieldGet(this, _SqlStack_families, "f").keys()].map((n) => `"${n}"`).join(', ') || '(none)'}`);
|
|
114
|
+
}
|
|
115
|
+
return fam;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Bind a family registration to a concrete member for the duration of fn
|
|
119
|
+
* (spec 17 §10). The binding is flow-local to this SqlStack; the member's
|
|
120
|
+
* connection is leased lazily on first database resolution and released
|
|
121
|
+
* when fn settles. Rebinding a family to a different key while it has an
|
|
122
|
+
* active transaction fails deterministically (spec 17 §29).
|
|
123
|
+
*/
|
|
124
|
+
async withDatabase(family, key, fn) {
|
|
125
|
+
__classPrivateFieldGet(this, _SqlStack_instances, "m", _SqlStack_assertOpen).call(this);
|
|
126
|
+
const fam = this.family(family);
|
|
127
|
+
const { keyId } = fam.normalize(key);
|
|
128
|
+
const outer = currentBinding(this, family);
|
|
129
|
+
if (outer && outer.keyId !== keyId && outer.lease) {
|
|
130
|
+
const { getActiveTransaction } = await import('./transactions');
|
|
131
|
+
if (getActiveTransaction(outer.lease.entry)) {
|
|
132
|
+
throw new SqlStackError(`Cannot rebind database family "${family}" from "${outer.keyId}" to "${keyId}": ` +
|
|
133
|
+
'a transaction is active for the current member. Finish the transaction first.');
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
const frame = { stack: this, family, keyInput: key, keyId };
|
|
137
|
+
try {
|
|
138
|
+
return await runWithBinding(frame, fn);
|
|
139
|
+
}
|
|
140
|
+
finally {
|
|
141
|
+
await frame.lease?.release();
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Async database resolution for query/transaction execution. Static
|
|
146
|
+
* registrations resolve directly; family registrations resolve through the
|
|
147
|
+
* active flow-local binding, opening/leasing the member on first use.
|
|
148
|
+
*/
|
|
149
|
+
async resolveEntry(name) {
|
|
150
|
+
__classPrivateFieldGet(this, _SqlStack_instances, "m", _SqlStack_assertOpen).call(this);
|
|
151
|
+
const key = name ??
|
|
152
|
+
__classPrivateFieldGet(this, _SqlStack_defaultName, "f") ??
|
|
153
|
+
// A stack whose only registration is one family treats it as default.
|
|
154
|
+
(__classPrivateFieldGet(this, _SqlStack_entries, "f").size === 0 && __classPrivateFieldGet(this, _SqlStack_families, "f").size === 1
|
|
155
|
+
? [...__classPrivateFieldGet(this, _SqlStack_families, "f").keys()][0]
|
|
156
|
+
: undefined);
|
|
157
|
+
if (key !== undefined) {
|
|
158
|
+
const entry = __classPrivateFieldGet(this, _SqlStack_entries, "f").get(key);
|
|
159
|
+
if (entry)
|
|
160
|
+
return entry;
|
|
161
|
+
const fam = __classPrivateFieldGet(this, _SqlStack_families, "f").get(key);
|
|
162
|
+
if (fam) {
|
|
163
|
+
const frame = currentBinding(this, key);
|
|
164
|
+
if (!frame) {
|
|
165
|
+
throw new SqlStackError(`SQLStack database family "${key}" requires a concrete database key. ` +
|
|
166
|
+
'No active binding exists for this execution. Establish the database at the ' +
|
|
167
|
+
`orchestration boundary with sqlStack.withDatabase("${key}", key, ...) ` +
|
|
168
|
+
'or acquire a member explicitly via sqlStack.family(...).with(...).');
|
|
169
|
+
}
|
|
170
|
+
if (!frame.lease) {
|
|
171
|
+
frame.lease = await fam.acquire(frame.keyInput);
|
|
172
|
+
}
|
|
173
|
+
return frame.lease.entry;
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
return this.getEntry(name);
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Set this stack's SQL resolver. When `options.classes` supplies the
|
|
180
|
+
* repository catalog, manifest coverage is validated from those classes'
|
|
181
|
+
* immutable metadata (environment-local, unpollutable by unrelated
|
|
182
|
+
* imports). Without a catalog, coverage falls back to the deprecated
|
|
183
|
+
* process-global decorated list.
|
|
184
|
+
*/
|
|
185
|
+
useResolver(resolver, options) {
|
|
186
|
+
__classPrivateFieldGet(this, _SqlStack_instances, "m", _SqlStack_assertOpen).call(this);
|
|
187
|
+
if (resolver instanceof ManifestResolver && resolver.options.assert !== false) {
|
|
188
|
+
if (options?.classes) {
|
|
189
|
+
assertManifestCoversClasses(resolver, options.classes);
|
|
190
|
+
}
|
|
191
|
+
else {
|
|
192
|
+
assertManifestCoverage(resolver);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
__classPrivateFieldSet(this, _SqlStack_resolver, resolver, "f");
|
|
196
|
+
return this;
|
|
197
|
+
}
|
|
198
|
+
resolver() {
|
|
199
|
+
return __classPrivateFieldGet(this, _SqlStack_resolver, "f");
|
|
200
|
+
}
|
|
201
|
+
get closed() {
|
|
202
|
+
return __classPrivateFieldGet(this, _SqlStack_closed, "f");
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Close owned database adapters exactly once and release runtime resources.
|
|
206
|
+
* Externally supplied databases (owned: false) are not touched. Failures are
|
|
207
|
+
* collected and reported with database identity rather than swallowed.
|
|
208
|
+
*/
|
|
209
|
+
async close() {
|
|
210
|
+
if (__classPrivateFieldGet(this, _SqlStack_closed, "f"))
|
|
211
|
+
return;
|
|
212
|
+
__classPrivateFieldSet(this, _SqlStack_closed, true, "f");
|
|
213
|
+
const failures = [];
|
|
214
|
+
for (const entry of __classPrivateFieldGet(this, _SqlStack_entries, "f").values()) {
|
|
215
|
+
if (!entry.owned)
|
|
216
|
+
continue;
|
|
217
|
+
try {
|
|
218
|
+
await entry.db.close();
|
|
219
|
+
}
|
|
220
|
+
catch (err) {
|
|
221
|
+
failures.push(`"${entry.name}": ${err?.message ?? String(err)}`);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
for (const fam of __classPrivateFieldGet(this, _SqlStack_families, "f").values()) {
|
|
225
|
+
try {
|
|
226
|
+
await fam.closeAll();
|
|
227
|
+
}
|
|
228
|
+
catch (err) {
|
|
229
|
+
failures.push(err?.message ?? String(err));
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
__classPrivateFieldGet(this, _SqlStack_entries, "f").clear();
|
|
233
|
+
__classPrivateFieldGet(this, _SqlStack_families, "f").clear();
|
|
234
|
+
__classPrivateFieldSet(this, _SqlStack_resolver, undefined, "f");
|
|
235
|
+
if (failures.length) {
|
|
236
|
+
throw new SqlStackError(`SqlStack close failed for ${failures.join(', ')}`);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
_SqlStack_entries = new WeakMap(), _SqlStack_families = new WeakMap(), _SqlStack_defaultName = new WeakMap(), _SqlStack_resolver = new WeakMap(), _SqlStack_closed = new WeakMap(), _SqlStack_instances = new WeakSet(), _SqlStack_assertOpen = function _SqlStack_assertOpen() {
|
|
241
|
+
if (__classPrivateFieldGet(this, _SqlStack_closed, "f")) {
|
|
242
|
+
throw new SqlStackError('SqlStack has been closed; its owning root was disposed.');
|
|
243
|
+
}
|
|
244
|
+
}, _SqlStack_registeredNames = function _SqlStack_registeredNames() {
|
|
245
|
+
const names = [
|
|
246
|
+
...[...__classPrivateFieldGet(this, _SqlStack_entries, "f").keys()].map((n) => `"${n}"`),
|
|
247
|
+
...[...__classPrivateFieldGet(this, _SqlStack_families, "f").keys()].map((n) => `"${n}" (family)`),
|
|
248
|
+
];
|
|
249
|
+
return names.length ? names.join(', ') : '(none)';
|
|
250
|
+
};
|
|
251
|
+
//# sourceMappingURL=stack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stack.js","sourceRoot":"","sources":["../../src/stack.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Database } from './registry';\nimport type { SqlResolver } from './core/resolver';\nimport {\n setGlobalResolver,\n clearGlobalResolver,\n ManifestResolver,\n assertManifestCoverage,\n assertManifestCoversClasses,\n} from './core/resolver';\nimport { SqlStackError } from './core/errors';\nimport { FamilyRuntime } from './family';\nimport type { FamilyConfig, FamilyMemberEntry, DatabaseLease } from './family';\nimport { currentBinding, runWithBinding, BindingFrame } from './familyBinding';\n\n/**\n * Concrete database identity inside one SqlStack instance.\n *\n * The entry OBJECT is the identity: two roots that both register a database\n * under the name \"primary\" produce two distinct DatabaseEntry instances, so\n * transaction lookup, caches, and diagnostics keyed by entry can never collide\n * across roots merely because the registration text matches.\n *\n * Dynamic database families (spec 17) extend this identity with a normalized\n * key; a static database is the no-key case.\n */\nexport interface DatabaseEntry {\n readonly name: string;\n readonly db: Database;\n /** Close() closes owned databases; externally supplied ones are left open. */\n readonly owned: boolean;\n /** The stack this entry belongs to, for diagnostics and mismatch checks. */\n readonly stack: SqlStack;\n}\n\nexport type DatabaseRegistration =\n | Database\n | {\n db: Database | (() => Database);\n /** Default false for direct Database values, true for factories. */\n owned?: boolean;\n };\n\nexport interface SqlStackConfig {\n databases?: Record<string, DatabaseRegistration>;\n /** Name of the default database. Required when more than one is registered. */\n default?: string;\n resolver?: SqlResolver;\n}\n\n/**\n * Environment-owned SQLStack runtime (spec 16 §12-13, repo spec 19 §3-5).\n *\n * One instance per owning IoC root; child scopes resolve the root's Singleton.\n * Native @Query/transaction/resolver execution goes through an instance —\n * never through the process-global SqlStackDB registry.\n */\nexport class SqlStack {\n /**\n * @deprecated Legacy v2 process-global resolver registration\n * (`SqlStack.useResolver(...)`). Forwards to the deprecated global state,\n * which is only consulted when no IoC environment is active. Use the\n * per-instance `useResolver` / SqlStackConfig.resolver instead.\n */\n static useResolver(resolver: SqlResolver): void {\n setGlobalResolver(resolver);\n }\n\n /** @deprecated See static useResolver. */\n static clearResolver(): void {\n clearGlobalResolver();\n }\n\n #entries = new Map<string, DatabaseEntry>();\n #families = new Map<string, FamilyRuntime<any>>();\n #defaultName: string | undefined;\n #resolver: SqlResolver | undefined;\n #closed = false;\n\n constructor(config?: SqlStackConfig) {\n if (config?.databases) {\n for (const [name, reg] of Object.entries(config.databases)) {\n if (typeof reg === 'object' && reg !== null && 'db' in reg) {\n const db = typeof reg.db === 'function' ? reg.db() : reg.db;\n this.register(name, db, { owned: reg.owned ?? typeof reg.db === 'function' });\n } else {\n this.register(name, reg as Database);\n }\n }\n }\n if (config?.default) this.setDefault(config.default);\n if (config?.resolver) this.useResolver(config.resolver);\n }\n\n register(name: string, db: Database, options?: { owned?: boolean; default?: boolean }): this {\n this.#assertOpen();\n const entry: DatabaseEntry = { name, db, owned: options?.owned ?? false, stack: this };\n this.#entries.set(name, entry);\n if (options?.default || this.#entries.size === 1) {\n this.#defaultName ??= name;\n if (options?.default) this.#defaultName = name;\n }\n return this;\n }\n\n setDefault(name: string): this {\n this.#assertOpen();\n if (!this.#entries.has(name)) {\n throw new SqlStackError(\n `SqlStack has no database registered under \"${name}\". Registered: ${this.#registeredNames()}`\n );\n }\n this.#defaultName = name;\n return this;\n }\n\n getEntry(name?: string): DatabaseEntry {\n this.#assertOpen();\n const key = name ?? this.#defaultName;\n if (!key) {\n throw new SqlStackError(\n 'SqlStack has no default database. Register one with { default: true } or call setDefault(name).'\n );\n }\n const entry = this.#entries.get(key);\n if (!entry) {\n throw new SqlStackError(\n `SqlStack has no database registered under \"${key}\". Registered: ${this.#registeredNames()}`\n );\n }\n return entry;\n }\n\n database(name?: string): Database {\n return this.getEntry(name).db;\n }\n\n has(name: string): boolean {\n return this.#entries.has(name) || this.#families.has(name);\n }\n\n /**\n * Register a dynamic database family (spec 17): one registration whose\n * concrete member is selected per execution flow via withDatabase(...).\n */\n registerFamily<K = string>(name: string, config: FamilyConfig<K>): this {\n this.#assertOpen();\n if (this.#entries.has(name)) {\n throw new SqlStackError(`\"${name}\" is already registered as a static database.`);\n }\n this.#families.set(name, new FamilyRuntime(this, name, config));\n return this;\n }\n\n family<K = string>(name: string): FamilyRuntime<K> {\n const fam = this.#families.get(name);\n if (!fam) {\n throw new SqlStackError(\n `SqlStack has no database family registered under \"${name}\". Families: ${\n [...this.#families.keys()].map((n) => `\"${n}\"`).join(', ') || '(none)'\n }`\n );\n }\n return fam;\n }\n\n /**\n * Bind a family registration to a concrete member for the duration of fn\n * (spec 17 §10). The binding is flow-local to this SqlStack; the member's\n * connection is leased lazily on first database resolution and released\n * when fn settles. Rebinding a family to a different key while it has an\n * active transaction fails deterministically (spec 17 §29).\n */\n async withDatabase<T>(family: string, key: unknown, fn: () => Promise<T>): Promise<T> {\n this.#assertOpen();\n const fam = this.family(family);\n const { keyId } = fam.normalize(key);\n\n const outer = currentBinding(this, family);\n if (outer && outer.keyId !== keyId && outer.lease) {\n const { getActiveTransaction } = await import('./transactions');\n if (getActiveTransaction(outer.lease.entry)) {\n throw new SqlStackError(\n `Cannot rebind database family \"${family}\" from \"${outer.keyId}\" to \"${keyId}\": ` +\n 'a transaction is active for the current member. Finish the transaction first.'\n );\n }\n }\n\n const frame: BindingFrame = { stack: this, family, keyInput: key, keyId };\n try {\n return await runWithBinding(frame, fn);\n } finally {\n await frame.lease?.release();\n }\n }\n\n /**\n * Async database resolution for query/transaction execution. Static\n * registrations resolve directly; family registrations resolve through the\n * active flow-local binding, opening/leasing the member on first use.\n */\n async resolveEntry(name?: string): Promise<DatabaseEntry> {\n this.#assertOpen();\n const key =\n name ??\n this.#defaultName ??\n // A stack whose only registration is one family treats it as default.\n (this.#entries.size === 0 && this.#families.size === 1\n ? [...this.#families.keys()][0]\n : undefined);\n if (key !== undefined) {\n const entry = this.#entries.get(key);\n if (entry) return entry;\n const fam = this.#families.get(key);\n if (fam) {\n const frame = currentBinding(this, key);\n if (!frame) {\n throw new SqlStackError(\n `SQLStack database family \"${key}\" requires a concrete database key. ` +\n 'No active binding exists for this execution. Establish the database at the ' +\n `orchestration boundary with sqlStack.withDatabase(\"${key}\", key, ...) ` +\n 'or acquire a member explicitly via sqlStack.family(...).with(...).'\n );\n }\n if (!frame.lease) {\n frame.lease = await fam.acquire(frame.keyInput);\n }\n return frame.lease.entry;\n }\n }\n return this.getEntry(name);\n }\n\n /**\n * Set this stack's SQL resolver. When `options.classes` supplies the\n * repository catalog, manifest coverage is validated from those classes'\n * immutable metadata (environment-local, unpollutable by unrelated\n * imports). Without a catalog, coverage falls back to the deprecated\n * process-global decorated list.\n */\n useResolver(\n resolver: SqlResolver,\n options?: { classes?: ReadonlyArray<abstract new (...args: any[]) => any> }\n ): this {\n this.#assertOpen();\n if (resolver instanceof ManifestResolver && resolver.options.assert !== false) {\n if (options?.classes) {\n assertManifestCoversClasses(resolver, options.classes);\n } else {\n assertManifestCoverage(resolver);\n }\n }\n this.#resolver = resolver;\n return this;\n }\n\n resolver(): SqlResolver | undefined {\n return this.#resolver;\n }\n\n get closed(): boolean {\n return this.#closed;\n }\n\n /**\n * Close owned database adapters exactly once and release runtime resources.\n * Externally supplied databases (owned: false) are not touched. Failures are\n * collected and reported with database identity rather than swallowed.\n */\n async close(): Promise<void> {\n if (this.#closed) return;\n this.#closed = true;\n const failures: string[] = [];\n for (const entry of this.#entries.values()) {\n if (!entry.owned) continue;\n try {\n await entry.db.close();\n } catch (err: any) {\n failures.push(`\"${entry.name}\": ${err?.message ?? String(err)}`);\n }\n }\n for (const fam of this.#families.values()) {\n try {\n await fam.closeAll();\n } catch (err: any) {\n failures.push(err?.message ?? String(err));\n }\n }\n this.#entries.clear();\n this.#families.clear();\n this.#resolver = undefined;\n if (failures.length) {\n throw new SqlStackError(`SqlStack close failed for ${failures.join(', ')}`);\n }\n }\n\n #assertOpen(): void {\n if (this.#closed) {\n throw new SqlStackError('SqlStack has been closed; its owning root was disposed.');\n }\n }\n\n #registeredNames(): string {\n const names = [\n ...[...this.#entries.keys()].map((n) => `\"${n}\"`),\n ...[...this.#families.keys()].map((n) => `\"${n}\" (family)`),\n ];\n return names.length ? names.join(', ') : '(none)';\n }\n}\n"]}
|