sqlstack 2.0.0 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (156) hide show
  1. package/dist/cjs/codegen/generateManifest.d.ts +12 -0
  2. package/dist/cjs/codegen/generateManifest.d.ts.map +1 -1
  3. package/dist/cjs/codegen/generateManifest.js +21 -11
  4. package/dist/cjs/codegen/generateManifest.js.map +1 -1
  5. package/dist/cjs/core/resolver.d.ts +25 -12
  6. package/dist/cjs/core/resolver.d.ts.map +1 -1
  7. package/dist/cjs/core/resolver.js +66 -20
  8. package/dist/cjs/core/resolver.js.map +1 -1
  9. package/dist/cjs/core/sourceScanResolver.d.ts +25 -0
  10. package/dist/cjs/core/sourceScanResolver.d.ts.map +1 -0
  11. package/dist/cjs/core/sourceScanResolver.js +56 -0
  12. package/dist/cjs/core/sourceScanResolver.js.map +1 -0
  13. package/dist/cjs/decorators/query.d.ts.map +1 -1
  14. package/dist/cjs/decorators/query.js +276 -245
  15. package/dist/cjs/decorators/query.js.map +1 -1
  16. package/dist/cjs/families/sqliteFamily.d.ts +26 -0
  17. package/dist/cjs/families/sqliteFamily.d.ts.map +1 -0
  18. package/dist/cjs/families/sqliteFamily.js +187 -0
  19. package/dist/cjs/families/sqliteFamily.js.map +1 -0
  20. package/dist/cjs/family.d.ts +69 -0
  21. package/dist/cjs/family.d.ts.map +1 -0
  22. package/dist/cjs/family.js +206 -0
  23. package/dist/cjs/family.js.map +1 -0
  24. package/dist/cjs/familyBinding.d.ts +22 -0
  25. package/dist/cjs/familyBinding.d.ts.map +1 -0
  26. package/dist/cjs/familyBinding.js +22 -0
  27. package/dist/cjs/familyBinding.js.map +1 -0
  28. package/dist/cjs/index.d.ts +10 -1
  29. package/dist/cjs/index.d.ts.map +1 -1
  30. package/dist/cjs/index.js +17 -2
  31. package/dist/cjs/index.js.map +1 -1
  32. package/dist/cjs/ioc.d.ts +22 -0
  33. package/dist/cjs/ioc.d.ts.map +1 -0
  34. package/dist/cjs/ioc.js +35 -0
  35. package/dist/cjs/ioc.js.map +1 -0
  36. package/dist/cjs/run.d.ts +29 -0
  37. package/dist/cjs/run.d.ts.map +1 -0
  38. package/dist/cjs/run.js +38 -0
  39. package/dist/cjs/run.js.map +1 -0
  40. package/dist/cjs/runtime.d.ts +25 -0
  41. package/dist/cjs/runtime.d.ts.map +1 -0
  42. package/dist/cjs/runtime.js +133 -0
  43. package/dist/cjs/runtime.js.map +1 -0
  44. package/dist/cjs/stack.d.ts +101 -0
  45. package/dist/cjs/stack.d.ts.map +1 -0
  46. package/dist/cjs/stack.js +288 -0
  47. package/dist/cjs/stack.js.map +1 -0
  48. package/dist/cjs/testing/builder.d.ts +29 -0
  49. package/dist/cjs/testing/builder.d.ts.map +1 -0
  50. package/dist/cjs/testing/builder.js +131 -0
  51. package/dist/cjs/testing/builder.js.map +1 -0
  52. package/dist/cjs/testing/index.d.ts +14 -0
  53. package/dist/cjs/testing/index.d.ts.map +1 -0
  54. package/dist/cjs/testing/index.js +22 -0
  55. package/dist/cjs/testing/index.js.map +1 -0
  56. package/dist/cjs/testing/postgres/allocator.d.ts +17 -0
  57. package/dist/cjs/testing/postgres/allocator.d.ts.map +1 -0
  58. package/dist/cjs/testing/postgres/allocator.js +54 -0
  59. package/dist/cjs/testing/postgres/allocator.js.map +1 -0
  60. package/dist/cjs/testing/postgres/database.d.ts +21 -0
  61. package/dist/cjs/testing/postgres/database.d.ts.map +1 -0
  62. package/dist/cjs/testing/postgres/database.js +39 -0
  63. package/dist/cjs/testing/postgres/database.js.map +1 -0
  64. package/dist/cjs/testing/postgres/loadData.d.ts +31 -0
  65. package/dist/cjs/testing/postgres/loadData.d.ts.map +1 -0
  66. package/dist/cjs/testing/postgres/loadData.js +184 -0
  67. package/dist/cjs/testing/postgres/loadData.js.map +1 -0
  68. package/dist/cjs/testing/postgres/server.d.ts +19 -0
  69. package/dist/cjs/testing/postgres/server.d.ts.map +1 -0
  70. package/dist/cjs/testing/postgres/server.js +78 -0
  71. package/dist/cjs/testing/postgres/server.js.map +1 -0
  72. package/dist/cjs/testing/schema/ddl.d.ts +5 -0
  73. package/dist/cjs/testing/schema/ddl.d.ts.map +1 -0
  74. package/dist/cjs/testing/schema/ddl.js +70 -0
  75. package/dist/cjs/testing/schema/ddl.js.map +1 -0
  76. package/dist/cjs/testing/schema/normalize.d.ts +7 -0
  77. package/dist/cjs/testing/schema/normalize.d.ts.map +1 -0
  78. package/dist/cjs/testing/schema/normalize.js +202 -0
  79. package/dist/cjs/testing/schema/normalize.js.map +1 -0
  80. package/dist/cjs/testing/schema/parser.d.ts +9 -0
  81. package/dist/cjs/testing/schema/parser.d.ts.map +1 -0
  82. package/dist/cjs/testing/schema/parser.js +80 -0
  83. package/dist/cjs/testing/schema/parser.js.map +1 -0
  84. package/dist/cjs/testing/schema/types.d.ts +63 -0
  85. package/dist/cjs/testing/schema/types.d.ts.map +1 -0
  86. package/dist/cjs/testing/schema/types.js +6 -0
  87. package/dist/cjs/testing/schema/types.js.map +1 -0
  88. package/dist/cjs/testing/sqlite/builder.d.ts +24 -0
  89. package/dist/cjs/testing/sqlite/builder.d.ts.map +1 -0
  90. package/dist/cjs/testing/sqlite/builder.js +134 -0
  91. package/dist/cjs/testing/sqlite/builder.js.map +1 -0
  92. package/dist/cjs/testing/sqlite/database.d.ts +18 -0
  93. package/dist/cjs/testing/sqlite/database.d.ts.map +1 -0
  94. package/dist/cjs/testing/sqlite/database.js +123 -0
  95. package/dist/cjs/testing/sqlite/database.js.map +1 -0
  96. package/dist/cjs/testing/sqlite/loadData.d.ts +7 -0
  97. package/dist/cjs/testing/sqlite/loadData.d.ts.map +1 -0
  98. package/dist/cjs/testing/sqlite/loadData.js +55 -0
  99. package/dist/cjs/testing/sqlite/loadData.js.map +1 -0
  100. package/dist/cjs/transactions.d.ts +14 -5
  101. package/dist/cjs/transactions.d.ts.map +1 -1
  102. package/dist/cjs/transactions.js +40 -24
  103. package/dist/cjs/transactions.js.map +1 -1
  104. package/dist/esm/codegen/generateManifest.js +20 -11
  105. package/dist/esm/codegen/generateManifest.js.map +1 -1
  106. package/dist/esm/core/resolver.js +59 -19
  107. package/dist/esm/core/resolver.js.map +1 -1
  108. package/dist/esm/core/sourceScanResolver.js +51 -0
  109. package/dist/esm/core/sourceScanResolver.js.map +1 -0
  110. package/dist/esm/decorators/query.js +278 -247
  111. package/dist/esm/decorators/query.js.map +1 -1
  112. package/dist/esm/families/sqliteFamily.js +151 -0
  113. package/dist/esm/families/sqliteFamily.js.map +1 -0
  114. package/dist/esm/family.js +202 -0
  115. package/dist/esm/family.js.map +1 -0
  116. package/dist/esm/familyBinding.js +18 -0
  117. package/dist/esm/familyBinding.js.map +1 -0
  118. package/dist/esm/index.js +10 -1
  119. package/dist/esm/index.js.map +1 -1
  120. package/dist/esm/ioc.js +32 -0
  121. package/dist/esm/ioc.js.map +1 -0
  122. package/dist/esm/run.js +34 -0
  123. package/dist/esm/run.js.map +1 -0
  124. package/dist/esm/runtime.js +94 -0
  125. package/dist/esm/runtime.js.map +1 -0
  126. package/dist/esm/stack.js +251 -0
  127. package/dist/esm/stack.js.map +1 -0
  128. package/dist/esm/testing/builder.js +95 -0
  129. package/dist/esm/testing/builder.js.map +1 -0
  130. package/dist/esm/testing/index.js +9 -0
  131. package/dist/esm/testing/index.js.map +1 -0
  132. package/dist/esm/testing/postgres/allocator.js +49 -0
  133. package/dist/esm/testing/postgres/allocator.js.map +1 -0
  134. package/dist/esm/testing/postgres/database.js +36 -0
  135. package/dist/esm/testing/postgres/database.js.map +1 -0
  136. package/dist/esm/testing/postgres/loadData.js +176 -0
  137. package/dist/esm/testing/postgres/loadData.js.map +1 -0
  138. package/dist/esm/testing/postgres/server.js +69 -0
  139. package/dist/esm/testing/postgres/server.js.map +1 -0
  140. package/dist/esm/testing/schema/ddl.js +65 -0
  141. package/dist/esm/testing/schema/ddl.js.map +1 -0
  142. package/dist/esm/testing/schema/normalize.js +164 -0
  143. package/dist/esm/testing/schema/normalize.js.map +1 -0
  144. package/dist/esm/testing/schema/parser.js +43 -0
  145. package/dist/esm/testing/schema/parser.js.map +1 -0
  146. package/dist/esm/testing/schema/types.js +5 -0
  147. package/dist/esm/testing/schema/types.js.map +1 -0
  148. package/dist/esm/testing/sqlite/builder.js +98 -0
  149. package/dist/esm/testing/sqlite/builder.js.map +1 -0
  150. package/dist/esm/testing/sqlite/database.js +85 -0
  151. package/dist/esm/testing/sqlite/database.js.map +1 -0
  152. package/dist/esm/testing/sqlite/loadData.js +48 -0
  153. package/dist/esm/testing/sqlite/loadData.js.map +1 -0
  154. package/dist/esm/transactions.js +39 -24
  155. package/dist/esm/transactions.js.map +1 -1
  156. package/package.json +19 -2
@@ -0,0 +1,206 @@
1
+ "use strict";
2
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
3
+ if (kind === "m") throw new TypeError("Private method is not writable");
4
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
5
+ 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");
6
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
7
+ };
8
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
9
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
10
+ 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");
11
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
12
+ };
13
+ var _FamilyRuntime_instances, _FamilyRuntime_stack, _FamilyRuntime_provider, _FamilyRuntime_maxOpen, _FamilyRuntime_members, _FamilyRuntime_useTick, _FamilyRuntime_closed, _FamilyRuntime_member, _FamilyRuntime_open, _FamilyRuntime_closeHandle, _FamilyRuntime_evictIfNeeded, _FamilyRuntime_assertOpen;
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.FamilyRuntime = void 0;
16
+ const errors_1 = require("./core/errors");
17
+ function unsupported(family, op) {
18
+ throw new errors_1.SqlStackError(`Database family "${family}" does not support ${op}(): its provider declares no such capability.`);
19
+ }
20
+ class FamilyRuntime {
21
+ constructor(stack, name, config) {
22
+ _FamilyRuntime_instances.add(this);
23
+ _FamilyRuntime_stack.set(this, void 0);
24
+ _FamilyRuntime_provider.set(this, void 0);
25
+ _FamilyRuntime_maxOpen.set(this, void 0);
26
+ _FamilyRuntime_members.set(this, new Map());
27
+ _FamilyRuntime_useTick.set(this, 0);
28
+ _FamilyRuntime_closed.set(this, false);
29
+ __classPrivateFieldSet(this, _FamilyRuntime_stack, stack, "f");
30
+ this.name = name;
31
+ __classPrivateFieldSet(this, _FamilyRuntime_provider, config.provider, "f");
32
+ __classPrivateFieldSet(this, _FamilyRuntime_maxOpen, config.cache?.maxOpen ?? 16, "f");
33
+ }
34
+ normalize(input) {
35
+ const key = __classPrivateFieldGet(this, _FamilyRuntime_provider, "f").normalizeKey(input);
36
+ const keyId = __classPrivateFieldGet(this, _FamilyRuntime_provider, "f").keyId ? __classPrivateFieldGet(this, _FamilyRuntime_provider, "f").keyId(key) : String(key);
37
+ return { key, keyId };
38
+ }
39
+ /** Stable concrete identity for a key; no I/O. */
40
+ ref(input) {
41
+ return __classPrivateFieldGet(this, _FamilyRuntime_instances, "m", _FamilyRuntime_member).call(this, input).entry;
42
+ }
43
+ async exists(input) {
44
+ const { key } = this.normalize(input);
45
+ if (!__classPrivateFieldGet(this, _FamilyRuntime_provider, "f").exists)
46
+ unsupported(this.name, 'exists');
47
+ return __classPrivateFieldGet(this, _FamilyRuntime_provider, "f").exists(key);
48
+ }
49
+ async create(input) {
50
+ __classPrivateFieldGet(this, _FamilyRuntime_instances, "m", _FamilyRuntime_assertOpen).call(this);
51
+ const member = __classPrivateFieldGet(this, _FamilyRuntime_instances, "m", _FamilyRuntime_member).call(this, input);
52
+ if (!__classPrivateFieldGet(this, _FamilyRuntime_provider, "f").create)
53
+ unsupported(this.name, 'create');
54
+ const db = await __classPrivateFieldGet(this, _FamilyRuntime_provider, "f").create(member.key);
55
+ await db.close();
56
+ }
57
+ async ensure(input) {
58
+ __classPrivateFieldGet(this, _FamilyRuntime_instances, "m", _FamilyRuntime_assertOpen).call(this);
59
+ const member = __classPrivateFieldGet(this, _FamilyRuntime_instances, "m", _FamilyRuntime_member).call(this, input);
60
+ if (!__classPrivateFieldGet(this, _FamilyRuntime_provider, "f").ensure)
61
+ unsupported(this.name, 'ensure');
62
+ const db = await __classPrivateFieldGet(this, _FamilyRuntime_provider, "f").ensure(member.key);
63
+ await db.close();
64
+ }
65
+ /** Acquire a lease on an opened (existing) member. */
66
+ async acquire(input) {
67
+ var _a;
68
+ __classPrivateFieldGet(this, _FamilyRuntime_instances, "m", _FamilyRuntime_assertOpen).call(this);
69
+ const member = __classPrivateFieldGet(this, _FamilyRuntime_instances, "m", _FamilyRuntime_member).call(this, input);
70
+ await __classPrivateFieldGet(this, _FamilyRuntime_instances, "m", _FamilyRuntime_open).call(this, member);
71
+ member.leases++;
72
+ member.lastUsed = __classPrivateFieldSet(this, _FamilyRuntime_useTick, (_a = __classPrivateFieldGet(this, _FamilyRuntime_useTick, "f"), ++_a), "f");
73
+ let released = false;
74
+ return {
75
+ entry: member.entry,
76
+ release: async () => {
77
+ if (released)
78
+ return;
79
+ released = true;
80
+ member.leases = Math.max(0, member.leases - 1);
81
+ __classPrivateFieldGet(this, _FamilyRuntime_instances, "m", _FamilyRuntime_evictIfNeeded).call(this);
82
+ },
83
+ };
84
+ }
85
+ async with(input, fn) {
86
+ const lease = await this.acquire(input);
87
+ try {
88
+ return await fn(lease.entry);
89
+ }
90
+ finally {
91
+ await lease.release();
92
+ }
93
+ }
94
+ /** Close/evict a member's cached handle; the database itself is preserved. */
95
+ async closeMember(input) {
96
+ const { keyId } = this.normalize(input);
97
+ const member = __classPrivateFieldGet(this, _FamilyRuntime_members, "f").get(keyId);
98
+ if (!member?.db)
99
+ return;
100
+ if (member.leases > 0) {
101
+ throw new errors_1.SqlStackError(`Cannot close "${this.name}/${keyId}": ${member.leases} lease(s) are active.`);
102
+ }
103
+ await __classPrivateFieldGet(this, _FamilyRuntime_instances, "m", _FamilyRuntime_closeHandle).call(this, member);
104
+ }
105
+ /** Physically delete a member. Fails while leased; closes the cached handle first. */
106
+ async deleteMember(input) {
107
+ __classPrivateFieldGet(this, _FamilyRuntime_instances, "m", _FamilyRuntime_assertOpen).call(this);
108
+ const member = __classPrivateFieldGet(this, _FamilyRuntime_instances, "m", _FamilyRuntime_member).call(this, input);
109
+ if (!__classPrivateFieldGet(this, _FamilyRuntime_provider, "f").delete)
110
+ unsupported(this.name, 'delete');
111
+ if (member.leases > 0) {
112
+ throw new errors_1.SqlStackError(`Cannot delete "${this.name}/${member.entry.keyId}": ${member.leases} lease(s) are active.`);
113
+ }
114
+ if (member.db)
115
+ await __classPrivateFieldGet(this, _FamilyRuntime_instances, "m", _FamilyRuntime_closeHandle).call(this, member);
116
+ await __classPrivateFieldGet(this, _FamilyRuntime_provider, "f").delete(member.key);
117
+ __classPrivateFieldGet(this, _FamilyRuntime_members, "f").delete(member.entry.keyId);
118
+ }
119
+ async inspect(input) {
120
+ const member = __classPrivateFieldGet(this, _FamilyRuntime_instances, "m", _FamilyRuntime_member).call(this, input);
121
+ if (!__classPrivateFieldGet(this, _FamilyRuntime_provider, "f").inspect)
122
+ unsupported(this.name, 'inspect');
123
+ const facts = await __classPrivateFieldGet(this, _FamilyRuntime_provider, "f").inspect(member.key);
124
+ return { ...facts, cached: !!member.db, activeLeases: member.leases };
125
+ }
126
+ /** Close every cached handle (root disposal). Databases are preserved. */
127
+ async closeAll() {
128
+ __classPrivateFieldSet(this, _FamilyRuntime_closed, true, "f");
129
+ const failures = [];
130
+ for (const member of __classPrivateFieldGet(this, _FamilyRuntime_members, "f").values()) {
131
+ if (!member.db)
132
+ continue;
133
+ try {
134
+ await __classPrivateFieldGet(this, _FamilyRuntime_instances, "m", _FamilyRuntime_closeHandle).call(this, member);
135
+ }
136
+ catch (err) {
137
+ failures.push(`"${this.name}/${member.entry.keyId}": ${err?.message ?? String(err)}`);
138
+ }
139
+ }
140
+ __classPrivateFieldGet(this, _FamilyRuntime_members, "f").clear();
141
+ if (failures.length) {
142
+ throw new errors_1.SqlStackError(`Family close failed for ${failures.join(', ')}`);
143
+ }
144
+ }
145
+ }
146
+ exports.FamilyRuntime = FamilyRuntime;
147
+ _FamilyRuntime_stack = new WeakMap(), _FamilyRuntime_provider = new WeakMap(), _FamilyRuntime_maxOpen = new WeakMap(), _FamilyRuntime_members = new WeakMap(), _FamilyRuntime_useTick = new WeakMap(), _FamilyRuntime_closed = new WeakMap(), _FamilyRuntime_instances = new WeakSet(), _FamilyRuntime_member = function _FamilyRuntime_member(input) {
148
+ const { key, keyId } = this.normalize(input);
149
+ let member = __classPrivateFieldGet(this, _FamilyRuntime_members, "f").get(keyId);
150
+ if (!member) {
151
+ const self = this;
152
+ const entry = {
153
+ name: this.name,
154
+ family: this.name,
155
+ keyId,
156
+ owned: true,
157
+ stack: __classPrivateFieldGet(this, _FamilyRuntime_stack, "f"),
158
+ get db() {
159
+ const state = __classPrivateFieldGet(self, _FamilyRuntime_members, "f").get(keyId);
160
+ if (!state?.db) {
161
+ throw new errors_1.SqlStackError(`Database family member "${self.name}/${keyId}" is not open. ` +
162
+ 'Acquire it through withDatabase(...)/family.with(...) before querying.');
163
+ }
164
+ return state.db;
165
+ },
166
+ };
167
+ member = { entry, leases: 0, lastUsed: 0 };
168
+ __classPrivateFieldGet(this, _FamilyRuntime_members, "f").set(keyId, member);
169
+ }
170
+ return Object.assign(member, { key: this.normalize(input).key });
171
+ }, _FamilyRuntime_open = async function _FamilyRuntime_open(member) {
172
+ if (member.db)
173
+ return;
174
+ if (!member.opening) {
175
+ member.opening = __classPrivateFieldGet(this, _FamilyRuntime_provider, "f").open(member.key).finally(() => {
176
+ member.opening = undefined;
177
+ });
178
+ member.opening.catch(() => undefined); // surfaced to awaiting callers
179
+ }
180
+ const db = await member.opening;
181
+ member.db = db;
182
+ __classPrivateFieldGet(this, _FamilyRuntime_instances, "m", _FamilyRuntime_evictIfNeeded).call(this);
183
+ }, _FamilyRuntime_closeHandle = async function _FamilyRuntime_closeHandle(member) {
184
+ const db = member.db;
185
+ member.db = undefined;
186
+ if (db)
187
+ await db.close();
188
+ }, _FamilyRuntime_evictIfNeeded = function _FamilyRuntime_evictIfNeeded() {
189
+ const open = [...__classPrivateFieldGet(this, _FamilyRuntime_members, "f").values()].filter((m) => m.db);
190
+ if (open.length <= __classPrivateFieldGet(this, _FamilyRuntime_maxOpen, "f"))
191
+ return;
192
+ const evictable = open
193
+ .filter((m) => m.leases === 0)
194
+ .sort((a, b) => a.lastUsed - b.lastUsed);
195
+ for (const member of evictable) {
196
+ if ([...__classPrivateFieldGet(this, _FamilyRuntime_members, "f").values()].filter((m) => m.db).length <= __classPrivateFieldGet(this, _FamilyRuntime_maxOpen, "f"))
197
+ break;
198
+ // Fire-and-forget close; eviction failures must not break the acquiring flow.
199
+ void __classPrivateFieldGet(this, _FamilyRuntime_instances, "m", _FamilyRuntime_closeHandle).call(this, member).catch(() => undefined);
200
+ }
201
+ }, _FamilyRuntime_assertOpen = function _FamilyRuntime_assertOpen() {
202
+ if (__classPrivateFieldGet(this, _FamilyRuntime_closed, "f")) {
203
+ throw new errors_1.SqlStackError(`Database family "${this.name}" belongs to a closed SqlStack.`);
204
+ }
205
+ };
206
+ //# sourceMappingURL=family.js.map
@@ -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,22 @@
1
+ import type { SqlStack } from './stack';
2
+ import type { DatabaseLease } from './family';
3
+ /**
4
+ * SQLStack-owned flow-local family binding (spec 17 §10-11).
5
+ *
6
+ * This carries WHICH concrete member of a dynamic family is selected for the
7
+ * current execution flow. It is deliberately separate from the IoC execution
8
+ * context (which owns root identity) and from transaction state. Frames are
9
+ * keyed by SqlStack instance, so two roots binding the same family name can
10
+ * never observe each other's selection.
11
+ */
12
+ export type BindingFrame = {
13
+ readonly stack: SqlStack;
14
+ readonly family: string;
15
+ readonly keyInput: unknown;
16
+ readonly keyId: string;
17
+ /** Acquired lazily on first database resolution inside the frame. */
18
+ lease?: DatabaseLease;
19
+ };
20
+ export declare function currentBinding(stack: SqlStack, family: string): BindingFrame | undefined;
21
+ export declare function runWithBinding<T>(frame: BindingFrame, fn: () => T): T;
22
+ //# sourceMappingURL=familyBinding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"familyBinding.d.ts","sourceRoot":"","sources":["../../src/familyBinding.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACxC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAE9C;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG;IACzB,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,qEAAqE;IACrE,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB,CAAC;AAIF,wBAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAQxF;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAGrE"}
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.currentBinding = currentBinding;
4
+ exports.runWithBinding = runWithBinding;
5
+ const node_async_hooks_1 = require("node:async_hooks");
6
+ const als = new node_async_hooks_1.AsyncLocalStorage();
7
+ function currentBinding(stack, family) {
8
+ const frames = als.getStore();
9
+ if (!frames)
10
+ return undefined;
11
+ for (let i = frames.length - 1; i >= 0; i--) {
12
+ const frame = frames[i];
13
+ if (frame.stack === stack && frame.family === family)
14
+ return frame;
15
+ }
16
+ return undefined;
17
+ }
18
+ function runWithBinding(frame, fn) {
19
+ const frames = als.getStore() ?? [];
20
+ return als.run([...frames, frame], fn);
21
+ }
22
+ //# sourceMappingURL=familyBinding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"familyBinding.js","sourceRoot":"","sources":["../../src/familyBinding.ts"],"names":[],"mappings":";;AAwBA,wCAQC;AAED,wCAGC;AArCD,uDAAqD;AAsBrD,MAAM,GAAG,GAAG,IAAI,oCAAiB,EAA2B,CAAC;AAE7D,SAAgB,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,SAAgB,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"]}
@@ -1,4 +1,5 @@
1
1
  export { sql, SqlFragment } from './sql';
2
+ export { run } from './run';
2
3
  export * from './decorators/queryBinder';
3
4
  export * from './decorators/query';
4
5
  export * from './decorators/defaults';
@@ -13,7 +14,15 @@ export * from './core/validator';
13
14
  export * from './utils/dto';
14
15
  export type { Dialect, WriteResult, PostgresWriteResult, QueryResult, Database } from './registry';
15
16
  export { SqlStackDB, IStackDB } from './registry';
17
+ export { SqlStack } from './stack';
18
+ export type { DatabaseEntry, DatabaseRegistration, SqlStackConfig } from './stack';
19
+ export { activeSqlStack, resolveExecution } from './runtime';
20
+ export { FamilyRuntime } from './family';
21
+ export type { DatabaseFamilyProvider, FamilyConfig, FamilyMemberEntry, DatabaseLease, DatabaseInspection, } from './family';
22
+ export { sqliteFamily } from './families/sqliteFamily';
23
+ export type { SqliteFamilyOptions } from './families/sqliteFamily';
16
24
  export type { SqlResolver, SqlManifest, SqlResolutionRequest, ManifestResolverOptions } from './core/resolver';
17
- export { SqlStack, FsResolver, ManifestResolver, MANIFEST_DIALECT_EXT } from './core/resolver';
25
+ export { FsResolver, ManifestResolver, MANIFEST_DIALECT_EXT } from './core/resolver';
26
+ export { SourceScanResolver } from './core/sourceScanResolver';
18
27
  export * from './binders/sqlBinder';
19
28
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAGzC,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;AAGlC,cAAc,gBAAgB,CAAC;AAG/B,cAAc,YAAY,CAAC;AAG3B,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AAGjC,cAAc,aAAa,CAAC;AAG5B,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACnG,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGlD,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC/G,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAG/F,cAAc,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,OAAO,CAAC;AAGzC,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC;AAG5B,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;AAGlC,cAAc,gBAAgB,CAAC;AAG/B,cAAc,YAAY,CAAC;AAG3B,cAAc,eAAe,CAAC;AAC9B,cAAc,kBAAkB,CAAC;AAGjC,cAAc,aAAa,CAAC;AAG5B,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACnG,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAGlD,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,YAAY,EAAE,aAAa,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACnF,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAG7D,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,YAAY,EACV,sBAAsB,EACtB,YAAY,EACZ,iBAAiB,EACjB,aAAa,EACb,kBAAkB,GACnB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,YAAY,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAGnE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,oBAAoB,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAC;AAC/G,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACrF,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAG/D,cAAc,qBAAqB,CAAC"}
package/dist/cjs/index.js CHANGED
@@ -14,11 +14,14 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.MANIFEST_DIALECT_EXT = exports.ManifestResolver = exports.FsResolver = exports.SqlStack = exports.SqlStackDB = exports.SqlFragment = exports.sql = void 0;
17
+ exports.SourceScanResolver = exports.MANIFEST_DIALECT_EXT = exports.ManifestResolver = exports.FsResolver = exports.sqliteFamily = exports.FamilyRuntime = exports.resolveExecution = exports.activeSqlStack = exports.SqlStack = exports.SqlStackDB = exports.run = exports.SqlFragment = exports.sql = void 0;
18
18
  // SQL Template Strings
19
19
  var sql_1 = require("./sql");
20
20
  Object.defineProperty(exports, "sql", { enumerable: true, get: function () { return sql_1.sql; } });
21
21
  Object.defineProperty(exports, "SqlFragment", { enumerable: true, get: function () { return sql_1.SqlFragment; } });
22
+ // Query body execution — `return run<T>()` inside a @Query method body
23
+ var run_1 = require("./run");
24
+ Object.defineProperty(exports, "run", { enumerable: true, get: function () { return run_1.run; } });
22
25
  // Decorators
23
26
  __exportStar(require("./decorators/queryBinder"), exports);
24
27
  __exportStar(require("./decorators/query"), exports);
@@ -38,11 +41,23 @@ __exportStar(require("./core/validator"), exports);
38
41
  __exportStar(require("./utils/dto"), exports);
39
42
  var registry_1 = require("./registry");
40
43
  Object.defineProperty(exports, "SqlStackDB", { enumerable: true, get: function () { return registry_1.SqlStackDB; } });
44
+ // Environment-owned runtime (v3): per-root SqlStack + active-context resolution
45
+ var stack_1 = require("./stack");
46
+ Object.defineProperty(exports, "SqlStack", { enumerable: true, get: function () { return stack_1.SqlStack; } });
47
+ var runtime_1 = require("./runtime");
48
+ Object.defineProperty(exports, "activeSqlStack", { enumerable: true, get: function () { return runtime_1.activeSqlStack; } });
49
+ Object.defineProperty(exports, "resolveExecution", { enumerable: true, get: function () { return runtime_1.resolveExecution; } });
50
+ // Dynamic database families (spec 17)
51
+ var family_1 = require("./family");
52
+ Object.defineProperty(exports, "FamilyRuntime", { enumerable: true, get: function () { return family_1.FamilyRuntime; } });
53
+ var sqliteFamily_1 = require("./families/sqliteFamily");
54
+ Object.defineProperty(exports, "sqliteFamily", { enumerable: true, get: function () { return sqliteFamily_1.sqliteFamily; } });
41
55
  var resolver_1 = require("./core/resolver");
42
- Object.defineProperty(exports, "SqlStack", { enumerable: true, get: function () { return resolver_1.SqlStack; } });
43
56
  Object.defineProperty(exports, "FsResolver", { enumerable: true, get: function () { return resolver_1.FsResolver; } });
44
57
  Object.defineProperty(exports, "ManifestResolver", { enumerable: true, get: function () { return resolver_1.ManifestResolver; } });
45
58
  Object.defineProperty(exports, "MANIFEST_DIALECT_EXT", { enumerable: true, get: function () { return resolver_1.MANIFEST_DIALECT_EXT; } });
59
+ var sourceScanResolver_1 = require("./core/sourceScanResolver");
60
+ Object.defineProperty(exports, "SourceScanResolver", { enumerable: true, get: function () { return sourceScanResolver_1.SourceScanResolver; } });
46
61
  // Legacy exports (kept for backward compatibility)
47
62
  __exportStar(require("./binders/sqlBinder"), exports);
48
63
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,uBAAuB;AACvB,6BAAyC;AAAhC,0FAAA,GAAG,OAAA;AAAE,kGAAA,WAAW,OAAA;AAEzB,aAAa;AACb,2DAAyC;AACzC,qDAAmC;AACnC,wDAAsC;AACtC,2DAAyC;AACzC,8DAA4C;AAC5C,yDAAuC;AACvC,oDAAkC;AAElC,eAAe;AACf,iDAA+B;AAE/B,WAAW;AACX,6CAA2B;AAE3B,wBAAwB;AACxB,gDAA8B;AAC9B,mDAAiC;AAEjC,aAAa;AACb,8CAA4B;AAI5B,uCAAkD;AAAzC,sGAAA,UAAU,OAAA;AAInB,4CAA+F;AAAtF,oGAAA,QAAQ,OAAA;AAAE,sGAAA,UAAU,OAAA;AAAE,4GAAA,gBAAgB,OAAA;AAAE,gHAAA,oBAAoB,OAAA;AAErE,mDAAmD;AACnD,sDAAoC","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// SQL Resolvers (v2): pluggable SQL source resolution\nexport type { SqlResolver, SqlManifest, SqlResolutionRequest, ManifestResolverOptions } from './core/resolver';\nexport { SqlStack, FsResolver, ManifestResolver, MANIFEST_DIALECT_EXT } from './core/resolver';\n\n// Legacy exports (kept for backward compatibility)\nexport * from './binders/sqlBinder';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,uBAAuB;AACvB,6BAAyC;AAAhC,0FAAA,GAAG,OAAA;AAAE,kGAAA,WAAW,OAAA;AAEzB,uEAAuE;AACvE,6BAA4B;AAAnB,0FAAA,GAAG,OAAA;AAEZ,aAAa;AACb,2DAAyC;AACzC,qDAAmC;AACnC,wDAAsC;AACtC,2DAAyC;AACzC,8DAA4C;AAC5C,yDAAuC;AACvC,oDAAkC;AAElC,eAAe;AACf,iDAA+B;AAE/B,WAAW;AACX,6CAA2B;AAE3B,wBAAwB;AACxB,gDAA8B;AAC9B,mDAAiC;AAEjC,aAAa;AACb,8CAA4B;AAI5B,uCAAkD;AAAzC,sGAAA,UAAU,OAAA;AAEnB,gFAAgF;AAChF,iCAAmC;AAA1B,iGAAA,QAAQ,OAAA;AAEjB,qCAA6D;AAApD,yGAAA,cAAc,OAAA;AAAE,2GAAA,gBAAgB,OAAA;AAEzC,sCAAsC;AACtC,mCAAyC;AAAhC,uGAAA,aAAa,OAAA;AAQtB,wDAAuD;AAA9C,4GAAA,YAAY,OAAA;AAKrB,4CAAqF;AAA5E,sGAAA,UAAU,OAAA;AAAE,4GAAA,gBAAgB,OAAA;AAAE,gHAAA,oBAAoB,OAAA;AAC3D,gEAA+D;AAAtD,wHAAA,kBAAkB,OAAA;AAE3B,mDAAmD;AACnD,sDAAoC","sourcesContent":["// SQL Template Strings\nexport { sql, SqlFragment } from './sql';\n\n// Query body execution — `return run<T>()` inside a @Query method body\nexport { run } from './run';\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"]}
@@ -0,0 +1,22 @@
1
+ import type { IContainerSetup } from '@noego/ioc';
2
+ import { SqlStackConfig } from './stack';
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 declare function registerSqlStack(container: IContainerSetup, config: SqlStackConfig | (() => SqlStackConfig)): {
20
+ dispose: () => Promise<void>;
21
+ };
22
+ //# sourceMappingURL=ioc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ioc.d.ts","sourceRoot":"","sources":["../../src/ioc.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,EAAY,cAAc,EAAE,MAAM,SAAS,CAAC;AAEnD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,eAAe,EAC1B,MAAM,EAAE,cAAc,GAAG,CAAC,MAAM,cAAc,CAAC,GAC9C;IAAE,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAelC"}
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.registerSqlStack = registerSqlStack;
4
+ const ioc_1 = require("@noego/ioc");
5
+ const stack_1 = require("./stack");
6
+ /**
7
+ * Root composition for SQLStack (repo spec 19 §6).
8
+ *
9
+ * Registers a per-root SqlStack Singleton built from normalized application
10
+ * configuration. Different roots in one process may register different
11
+ * database URLs/resolvers concurrently; child scopes resolve the owning
12
+ * root's instance under normal IoC semantics.
13
+ *
14
+ * This module is the only sqlstack module that imports @noego/ioc statically;
15
+ * core query execution reaches the active root through the IoC execution
16
+ * context without a hard dependency.
17
+ *
18
+ * Lifecycle: the returned dispose function closes SqlStack-owned database
19
+ * adapters. Call it when disposing the root (or wire it into the root's
20
+ * disposal hook where the container version supports one).
21
+ */
22
+ function registerSqlStack(container, config) {
23
+ let instance;
24
+ container.registerFunction(stack_1.SqlStack, () => {
25
+ instance = new stack_1.SqlStack(typeof config === 'function' ? config() : config);
26
+ return instance;
27
+ }, { loadAs: ioc_1.LoadAs.Singleton });
28
+ return {
29
+ dispose: async () => {
30
+ if (instance)
31
+ await instance.close();
32
+ },
33
+ };
34
+ }
35
+ //# sourceMappingURL=ioc.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ioc.js","sourceRoot":"","sources":["../../src/ioc.ts"],"names":[],"mappings":";;AAoBA,4CAkBC;AAtCD,oCAAoC;AAEpC,mCAAmD;AAEnD;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,gBAAgB,CAC9B,SAA0B,EAC1B,MAA+C;IAE/C,IAAI,QAA8B,CAAC;IAClC,SAAiB,CAAC,gBAAgB,CACjC,gBAAQ,EACR,GAAG,EAAE;QACH,QAAQ,GAAG,IAAI,gBAAQ,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,YAAM,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,29 @@
1
+ import { AsyncLocalStorage } from 'node:async_hooks';
2
+ /**
3
+ * Per-invocation context established by the @Query wrapper before the method
4
+ * body executes. `execute` performs the full query pipeline (resolve SQL,
5
+ * bind, execute, shape/transform/validate); `ran` records that the body
6
+ * invoked run(), so the wrapper returns the body's result verbatim instead
7
+ * of falling through to the legacy pipeline.
8
+ */
9
+ export type RunContext = {
10
+ execute: () => Promise<unknown>;
11
+ ran: boolean;
12
+ };
13
+ export declare const runStorage: AsyncLocalStorage<RunContext>;
14
+ /**
15
+ * Execute the current @Query method's SQL and return the finished result.
16
+ * Call it as the body of a @Query-decorated method in place of the legacy
17
+ * placeholder throw:
18
+ *
19
+ * @Query()
20
+ * async getUsers(active: boolean): Promise<User[]> {
21
+ * return run<User[]>();
22
+ * }
23
+ *
24
+ * Takes no arguments — the method's own arguments, database, SQL source,
25
+ * transaction, shaping, transform, and validation all come from the
26
+ * decorator context. The generic is a typing convenience only.
27
+ */
28
+ export declare function run<T = any>(): Promise<T>;
29
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAGrD;;;;;;GAMG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAChC,GAAG,EAAE,OAAO,CAAC;CACd,CAAC;AAUF,eAAO,MAAM,UAAU,EAA0B,iBAAiB,CAAC,UAAU,CAAC,CAAC;AAE/E;;;;;;;;;;;;;GAaG;AACH,wBAAsB,GAAG,CAAC,CAAC,GAAG,GAAG,KAAK,OAAO,CAAC,CAAC,CAAC,CAS/C"}
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runStorage = void 0;
4
+ exports.run = run;
5
+ const node_async_hooks_1 = require("node:async_hooks");
6
+ const errors_1 = require("./core/errors");
7
+ // Anchored on globalThis via Symbol.for so duplicated module instances
8
+ // (npm link, dual ESM/CJS loads) share one channel between the decorator
9
+ // and the run() the application imports.
10
+ const RUN_CHANNEL = Symbol.for('noego.sqlstack.runContext');
11
+ const anchor = globalThis;
12
+ if (!anchor[RUN_CHANNEL]) {
13
+ anchor[RUN_CHANNEL] = new node_async_hooks_1.AsyncLocalStorage();
14
+ }
15
+ exports.runStorage = anchor[RUN_CHANNEL];
16
+ /**
17
+ * Execute the current @Query method's SQL and return the finished result.
18
+ * Call it as the body of a @Query-decorated method in place of the legacy
19
+ * placeholder throw:
20
+ *
21
+ * @Query()
22
+ * async getUsers(active: boolean): Promise<User[]> {
23
+ * return run<User[]>();
24
+ * }
25
+ *
26
+ * Takes no arguments — the method's own arguments, database, SQL source,
27
+ * transaction, shaping, transform, and validation all come from the
28
+ * decorator context. The generic is a typing convenience only.
29
+ */
30
+ async function run() {
31
+ const ctx = exports.runStorage.getStore();
32
+ if (!ctx) {
33
+ throw new errors_1.SqlStackError('run() called outside a @Query method. It may only be invoked from the body of a @Query-decorated method.');
34
+ }
35
+ ctx.ran = true;
36
+ return ctx.execute();
37
+ }
38
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/run.ts"],"names":[],"mappings":";;;AAuCA,kBASC;AAhDD,uDAAqD;AACrD,0CAA8C;AAc9C,uEAAuE;AACvE,yEAAyE;AACzE,yCAAyC;AACzC,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;AAC5D,MAAM,MAAM,GAAG,UAA0C,CAAC;AAC1D,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC;IACzB,MAAM,CAAC,WAAW,CAAC,GAAG,IAAI,oCAAiB,EAAc,CAAC;AAC5D,CAAC;AACY,QAAA,UAAU,GAAG,MAAM,CAAC,WAAW,CAAkC,CAAC;AAE/E;;;;;;;;;;;;;GAaG;AACI,KAAK,UAAU,GAAG;IACvB,MAAM,GAAG,GAAG,kBAAU,CAAC,QAAQ,EAAE,CAAC;IAClC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,sBAAa,CACrB,0GAA0G,CAC3G,CAAC;IACJ,CAAC;IACD,GAAG,CAAC,GAAG,GAAG,IAAI,CAAC;IACf,OAAO,GAAG,CAAC,OAAO,EAAgB,CAAC;AACrC,CAAC","sourcesContent":["import { AsyncLocalStorage } from 'node:async_hooks';\nimport { SqlStackError } from './core/errors';\n\n/**\n * Per-invocation context established by the @Query wrapper before the method\n * body executes. `execute` performs the full query pipeline (resolve SQL,\n * bind, execute, shape/transform/validate); `ran` records that the body\n * invoked run(), so the wrapper returns the body's result verbatim instead\n * of falling through to the legacy pipeline.\n */\nexport type RunContext = {\n execute: () => Promise<unknown>;\n ran: boolean;\n};\n\n// Anchored on globalThis via Symbol.for so duplicated module instances\n// (npm link, dual ESM/CJS loads) share one channel between the decorator\n// and the run() the application imports.\nconst RUN_CHANNEL = Symbol.for('noego.sqlstack.runContext');\nconst anchor = globalThis as Record<PropertyKey, unknown>;\nif (!anchor[RUN_CHANNEL]) {\n anchor[RUN_CHANNEL] = new AsyncLocalStorage<RunContext>();\n}\nexport const runStorage = anchor[RUN_CHANNEL] as AsyncLocalStorage<RunContext>;\n\n/**\n * Execute the current @Query method's SQL and return the finished result.\n * Call it as the body of a @Query-decorated method in place of the legacy\n * placeholder throw:\n *\n * @Query()\n * async getUsers(active: boolean): Promise<User[]> {\n * return run<User[]>();\n * }\n *\n * Takes no arguments — the method's own arguments, database, SQL source,\n * transaction, shaping, transform, and validation all come from the\n * decorator context. The generic is a typing convenience only.\n */\nexport async function run<T = any>(): Promise<T> {\n const ctx = runStorage.getStore();\n if (!ctx) {\n throw new SqlStackError(\n 'run() called outside a @Query method. It may only be invoked from the body of a @Query-decorated method.'\n );\n }\n ctx.ran = true;\n return ctx.execute() as Promise<T>;\n}\n"]}
@@ -0,0 +1,25 @@
1
+ import { SqlStack, DatabaseEntry } from './stack';
2
+ import type { SqlResolver } from './core/resolver';
3
+ /** @internal Test-only: force re-detection of @noego/ioc. */
4
+ export declare function __resetIocDetection(): void;
5
+ /**
6
+ * The SqlStack for the active IoC execution context, or undefined when no
7
+ * IoC environment is active (or @noego/ioc is not installed).
8
+ *
9
+ * Throws when an environment IS active but has no SqlStack registered —
10
+ * silently falling back to global state under an active root is forbidden.
11
+ */
12
+ export declare function activeSqlStack(): Promise<SqlStack | undefined>;
13
+ export type ResolvedExecution = {
14
+ entry: DatabaseEntry;
15
+ resolver: SqlResolver | undefined;
16
+ /** True when resolved through an active IoC root's SqlStack. */
17
+ viaStack: boolean;
18
+ };
19
+ /**
20
+ * Resolve the concrete database entry (and SQL resolver) for one execution.
21
+ */
22
+ export declare function resolveExecution(dbName?: string): Promise<ResolvedExecution>;
23
+ /** @internal Resolve a legacy global-registry database as a DatabaseEntry. */
24
+ export declare function legacyEntry(dbName?: string): DatabaseEntry;
25
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAGlD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAmCnD,6DAA6D;AAC7D,wBAAgB,mBAAmB,IAAI,IAAI,CAE1C;AAED;;;;;;GAMG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC,CAsBpE;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,KAAK,EAAE,aAAa,CAAC;IACrB,QAAQ,EAAE,WAAW,GAAG,SAAS,CAAC;IAClC,gEAAgE;IAChE,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAUlF;AAyBD,8EAA8E;AAC9E,wBAAgB,WAAW,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,aAAa,CAQ1D"}