@veryfront/ext-content-mdx 0.1.1226 → 0.1.1228

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 (107) hide show
  1. package/esm/_dnt.polyfills.d.ts +105 -6
  2. package/esm/_dnt.polyfills.d.ts.map +1 -1
  3. package/esm/_dnt.polyfills.js +127 -1
  4. package/esm/deno.d.ts +17 -2
  5. package/esm/deno.js +24 -9
  6. package/esm/src/extensions/contract-registry-internal.d.ts +144 -0
  7. package/esm/src/extensions/contract-registry-internal.d.ts.map +1 -0
  8. package/esm/src/extensions/contract-registry-internal.js +642 -0
  9. package/esm/src/extensions/contracts.d.ts +16 -0
  10. package/esm/src/extensions/contracts.d.ts.map +1 -0
  11. package/esm/src/extensions/contracts.js +46 -0
  12. package/esm/src/extensions/errors.d.ts +16 -0
  13. package/esm/src/extensions/errors.d.ts.map +1 -0
  14. package/esm/src/extensions/errors.js +46 -0
  15. package/esm/src/extensions/first-party-import.d.ts +43 -0
  16. package/esm/src/extensions/first-party-import.d.ts.map +1 -0
  17. package/esm/src/extensions/first-party-import.js +377 -0
  18. package/esm/src/extensions/parser/yaml-defaults.d.ts +22 -0
  19. package/esm/src/extensions/parser/yaml-defaults.d.ts.map +1 -0
  20. package/esm/src/extensions/parser/yaml-defaults.js +57 -0
  21. package/esm/src/extensions/parser/yaml-parser.d.ts +59 -0
  22. package/esm/src/extensions/parser/yaml-parser.d.ts.map +1 -0
  23. package/esm/src/extensions/parser/yaml-parser.js +62 -0
  24. package/esm/src/extensions/recommendations.d.ts +8 -0
  25. package/esm/src/extensions/recommendations.d.ts.map +1 -0
  26. package/esm/src/extensions/recommendations.js +38 -0
  27. package/esm/src/extensions/runtime-validation.d.ts +21 -0
  28. package/esm/src/extensions/runtime-validation.d.ts.map +1 -0
  29. package/esm/src/extensions/runtime-validation.js +95 -0
  30. package/esm/src/observability/telemetry-error.d.ts.map +1 -1
  31. package/esm/src/observability/telemetry-error.js +15 -3
  32. package/esm/src/platform/compat/async-context.d.ts +8 -0
  33. package/esm/src/platform/compat/async-context.d.ts.map +1 -0
  34. package/esm/src/platform/compat/async-context.js +7 -0
  35. package/esm/src/platform/compat/std/front-matter-yaml.js +1 -1
  36. package/esm/src/platform/compat/std/yaml.d.ts +17 -0
  37. package/esm/src/platform/compat/std/yaml.d.ts.map +1 -0
  38. package/esm/src/platform/compat/std/yaml.js +39 -0
  39. package/esm/src/utils/constants/http.d.ts +8 -2
  40. package/esm/src/utils/constants/http.d.ts.map +1 -1
  41. package/esm/src/utils/constants/http.js +10 -2
  42. package/esm/src/utils/version-constant.d.ts +1 -1
  43. package/esm/src/utils/version-constant.js +1 -1
  44. package/package.json +2 -2
  45. package/esm/deps/jsr.io/@std/yaml/1.1.0/_chars.d.ts +0 -33
  46. package/esm/deps/jsr.io/@std/yaml/1.1.0/_chars.d.ts.map +0 -1
  47. package/esm/deps/jsr.io/@std/yaml/1.1.0/_chars.js +0 -48
  48. package/esm/deps/jsr.io/@std/yaml/1.1.0/_loader_state.d.ts +0 -64
  49. package/esm/deps/jsr.io/@std/yaml/1.1.0/_loader_state.d.ts.map +0 -1
  50. package/esm/deps/jsr.io/@std/yaml/1.1.0/_loader_state.js +0 -1371
  51. package/esm/deps/jsr.io/@std/yaml/1.1.0/_schema.d.ts +0 -44
  52. package/esm/deps/jsr.io/@std/yaml/1.1.0/_schema.d.ts.map +0 -1
  53. package/esm/deps/jsr.io/@std/yaml/1.1.0/_schema.js +0 -117
  54. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/binary.d.ts +0 -3
  55. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/binary.d.ts.map +0 -1
  56. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/binary.js +0 -103
  57. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/bool.d.ts +0 -3
  58. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/bool.d.ts.map +0 -1
  59. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/bool.js +0 -32
  60. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/float.d.ts +0 -3
  61. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/float.d.ts.map +0 -1
  62. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/float.js +0 -96
  63. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/int.d.ts +0 -3
  64. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/int.d.ts.map +0 -1
  65. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/int.js +0 -159
  66. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/map.d.ts +0 -3
  67. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/map.d.ts.map +0 -1
  68. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/map.js +0 -14
  69. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/merge.d.ts +0 -3
  70. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/merge.d.ts.map +0 -1
  71. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/merge.js +0 -10
  72. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/nil.d.ts +0 -3
  73. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/nil.d.ts.map +0 -1
  74. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/nil.js +0 -22
  75. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/omap.d.ts +0 -3
  76. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/omap.d.ts.map +0 -1
  77. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/omap.js +0 -29
  78. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/pairs.d.ts +0 -3
  79. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/pairs.d.ts.map +0 -1
  80. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/pairs.js +0 -19
  81. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/regexp.d.ts +0 -3
  82. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/regexp.d.ts.map +0 -1
  83. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/regexp.js +0 -30
  84. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/seq.d.ts +0 -3
  85. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/seq.d.ts.map +0 -1
  86. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/seq.js +0 -10
  87. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/set.d.ts +0 -3
  88. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/set.d.ts.map +0 -1
  89. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/set.js +0 -14
  90. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/str.d.ts +0 -3
  91. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/str.d.ts.map +0 -1
  92. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/str.js +0 -9
  93. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/timestamp.d.ts +0 -3
  94. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/timestamp.d.ts.map +0 -1
  95. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/timestamp.js +0 -81
  96. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/undefined.d.ts +0 -3
  97. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/undefined.d.ts.map +0 -1
  98. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type/undefined.js +0 -20
  99. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type.d.ts +0 -32
  100. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type.d.ts.map +0 -1
  101. package/esm/deps/jsr.io/@std/yaml/1.1.0/_type.js +0 -6
  102. package/esm/deps/jsr.io/@std/yaml/1.1.0/_utils.d.ts +0 -4
  103. package/esm/deps/jsr.io/@std/yaml/1.1.0/_utils.d.ts.map +0 -1
  104. package/esm/deps/jsr.io/@std/yaml/1.1.0/_utils.js +0 -13
  105. package/esm/deps/jsr.io/@std/yaml/1.1.0/parse.d.ts +0 -76
  106. package/esm/deps/jsr.io/@std/yaml/1.1.0/parse.d.ts.map +0 -1
  107. package/esm/deps/jsr.io/@std/yaml/1.1.0/parse.js +0 -91
@@ -0,0 +1,642 @@
1
+ /**
2
+ * Internal contract-registry ownership and active-use lifecycle.
3
+ *
4
+ * Public registry operations intentionally remain synchronous and preserve
5
+ * their existing signatures. Loader-owned registrations additionally carry
6
+ * an opaque generation identity so teardown can stop admission, drain active
7
+ * users, and remove only the exact entries that generation published.
8
+ *
9
+ * @internal
10
+ */
11
+ import { assertCanonicalNonEmptyString } from "./runtime-validation.js";
12
+ import { AsyncLocalStorage } from "../platform/compat/async-context.js";
13
+ const NativeAggregateError = AggregateError;
14
+ const NativeError = Error;
15
+ const NativeMap = Map;
16
+ const NativePromise = Promise;
17
+ const NativeSet = Set;
18
+ const apply = Reflect.apply;
19
+ const arrayIteratorSymbol = Symbol.iterator;
20
+ const arrayIterator = Array.prototype[arrayIteratorSymbol];
21
+ const createObject = Object.create;
22
+ const defineProperty = Object.defineProperty;
23
+ const freeze = Object.freeze;
24
+ const getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
25
+ const setPrototypeOf = Object.setPrototypeOf;
26
+ const mapClear = Map.prototype.clear;
27
+ const mapDelete = Map.prototype.delete;
28
+ const mapForEach = Map.prototype.forEach;
29
+ const mapGet = Map.prototype.get;
30
+ const mapSet = Map.prototype.set;
31
+ const setAdd = Set.prototype.add;
32
+ const setDelete = Set.prototype.delete;
33
+ const setForEach = Set.prototype.forEach;
34
+ const setHas = Set.prototype.has;
35
+ const setSizeGetter = (() => {
36
+ const getter = getOwnPropertyDescriptor(Set.prototype, "size")?.get;
37
+ if (getter === undefined) {
38
+ throw new NativeError("Set.prototype.size getter is unavailable");
39
+ }
40
+ return getter;
41
+ })();
42
+ const registeredContracts = new NativeMap();
43
+ const generationResolutionStorage = new AsyncLocalStorage();
44
+ const asyncLocalStorageGetStore = AsyncLocalStorage.prototype.getStore;
45
+ const asyncLocalStorageRun = AsyncLocalStorage.prototype.run;
46
+ function createRegistryResetToken() {
47
+ return freeze(createObject(null));
48
+ }
49
+ function createNullPrototypeRecord(record) {
50
+ return apply(setPrototypeOf, Object, [record, null]);
51
+ }
52
+ function createDataDescriptor(value, configurable = false, writable = false) {
53
+ const descriptor = createObject(null);
54
+ descriptor.configurable = configurable;
55
+ descriptor.enumerable = false;
56
+ descriptor.value = value;
57
+ descriptor.writable = writable;
58
+ return descriptor;
59
+ }
60
+ function appendArrayValue(array, value) {
61
+ const descriptor = createObject(null);
62
+ descriptor.configurable = true;
63
+ descriptor.enumerable = true;
64
+ descriptor.value = value;
65
+ descriptor.writable = true;
66
+ defineProperty(array, array.length, descriptor);
67
+ }
68
+ function copyArrayForAggregateError(source) {
69
+ const copy = [];
70
+ for (let index = 0; index < source.length; index += 1) {
71
+ appendArrayValue(copy, source[index]);
72
+ }
73
+ defineProperty(copy, arrayIteratorSymbol, createDataDescriptor(arrayIterator));
74
+ return copy;
75
+ }
76
+ function clearMap(map) {
77
+ apply(mapClear, map, []);
78
+ }
79
+ function deleteMapValue(map, key) {
80
+ return apply(mapDelete, map, [key]);
81
+ }
82
+ function forEachMapValue(map, callback) {
83
+ apply(mapForEach, map, [callback]);
84
+ }
85
+ function getMapValue(map, key) {
86
+ return apply(mapGet, map, [key]);
87
+ }
88
+ function setMapValue(map, key, value) {
89
+ apply(mapSet, map, [key, value]);
90
+ }
91
+ function addSetValue(set, value) {
92
+ apply(setAdd, set, [value]);
93
+ }
94
+ function deleteSetValue(set, value) {
95
+ return apply(setDelete, set, [value]);
96
+ }
97
+ function forEachSetValue(set, callback) {
98
+ apply(setForEach, set, [callback]);
99
+ }
100
+ function hasSetValue(set, value) {
101
+ return apply(setHas, set, [value]);
102
+ }
103
+ function getSetSize(set) {
104
+ return apply(setSizeGetter, set, []);
105
+ }
106
+ function createPinnedPromise(executor) {
107
+ const promise = new NativePromise(executor);
108
+ defineProperty(promise, "constructor", createDataDescriptor(NativePromise));
109
+ return promise;
110
+ }
111
+ function createResolvedPromise() {
112
+ return createPinnedPromise((resolve) => resolve());
113
+ }
114
+ function getScopedResolutionState() {
115
+ const scope = apply(asyncLocalStorageGetStore, generationResolutionStorage, []);
116
+ if (scope === undefined)
117
+ return undefined;
118
+ if (!scope.active || scope.resetToken !== contractRegistryResetToken) {
119
+ // A low-level reset is an epoch boundary. While stale cleanup is still
120
+ // running, suppress both its candidate overlay and fallback into the new
121
+ // global registry so it cannot act on replacement resources. Inactive
122
+ // inherited scopes stay blocked so detached descendants cannot outlive
123
+ // their teardown authority and later observe a replacement.
124
+ return null;
125
+ }
126
+ return scope;
127
+ }
128
+ function extensionTeardownUnavailable(name) {
129
+ return new NativeError(`Extension contract "${name}" is unavailable during extension teardown`);
130
+ }
131
+ function assertNoLifecycleAdmissionDuringTeardown(name) {
132
+ if (getScopedResolutionState() !== undefined) {
133
+ throw extensionTeardownUnavailable(name);
134
+ }
135
+ }
136
+ function assertCurrentMutationScope(operation) {
137
+ const scope = getScopedResolutionState();
138
+ if (scope === null) {
139
+ throw new NativeError(`Cannot ${operation} extension contracts from an expired teardown scope`);
140
+ }
141
+ return scope;
142
+ }
143
+ function assertNoGenerationTransitionDuringTeardown(operation) {
144
+ if (getScopedResolutionState() !== undefined) {
145
+ throw new NativeError(`Cannot ${operation} an extension contract generation during extension teardown`);
146
+ }
147
+ }
148
+ /**
149
+ * Reject candidate preparation before extension-controlled materialization or
150
+ * transition hooks can run inside a current or inherited teardown scope.
151
+ */
152
+ export function assertContractGenerationAdmissionAllowed() {
153
+ assertNoGenerationTransitionDuringTeardown("start");
154
+ }
155
+ let activeGeneration;
156
+ let stagingGeneration;
157
+ let failedGenerationUnavailable = false;
158
+ let contractRegistryResetToken = createRegistryResetToken();
159
+ function createEntry(implementation, generation) {
160
+ return freeze(createNullPrototypeRecord({
161
+ implementation,
162
+ generation,
163
+ }));
164
+ }
165
+ function assertStagingGeneration(generation) {
166
+ if (generation.status !== "staging" || stagingGeneration !== generation) {
167
+ throw new NativeError("Contract generation is not the active staging generation");
168
+ }
169
+ }
170
+ function unavailableDuringTransition(name) {
171
+ const entry = getMapValue(registeredContracts, name);
172
+ if (entry?.generation?.status === "retiring") {
173
+ return new NativeError(`Extension contract "${name}" is unavailable while its generation is retiring`);
174
+ }
175
+ if (stagingGeneration !== undefined) {
176
+ return new NativeError("Extension contracts are unavailable while a generation is staging");
177
+ }
178
+ if (failedGenerationUnavailable) {
179
+ return new NativeError("Extension contracts are unavailable because the previous generation failed");
180
+ }
181
+ return new NativeError(`Extension contract "${name}" is unavailable because its captured generation is no longer active`);
182
+ }
183
+ function notifyRetirement(generation, record) {
184
+ if (record.released ||
185
+ record.retirementNotified ||
186
+ record.retirementHandler === undefined ||
187
+ !generation.hasRetirementReason ||
188
+ !generation.retirementNotificationStarted) {
189
+ return;
190
+ }
191
+ record.retirementNotified = true;
192
+ generation.retirementNotificationDepth += 1;
193
+ try {
194
+ try {
195
+ runWithContractGenerationEpochSync(generation, () => {
196
+ apply(record.retirementHandler, undefined, [
197
+ generation.retirementReason,
198
+ ]);
199
+ });
200
+ }
201
+ catch (error) {
202
+ appendArrayValue(generation.retirementHandlerFailures, error);
203
+ }
204
+ }
205
+ finally {
206
+ generation.retirementNotificationDepth -= 1;
207
+ finishLeaseDrain(generation);
208
+ }
209
+ }
210
+ function finishLeaseDrain(generation) {
211
+ if (getSetSize(generation.leases) !== 0 ||
212
+ generation.retirementNotificationDepth !== 0) {
213
+ return;
214
+ }
215
+ const settle = generation.settleLeaseDrain;
216
+ generation.settleLeaseDrain = undefined;
217
+ generation.rejectLeaseDrain = undefined;
218
+ if (settle !== undefined)
219
+ apply(settle, undefined, []);
220
+ }
221
+ function getQuarantinedLeaseFailure(generation) {
222
+ let failure;
223
+ forEachSetValue(generation.leases, (record) => {
224
+ if (failure === undefined && record.quarantined) {
225
+ failure = record.quarantineFailure;
226
+ }
227
+ });
228
+ return failure;
229
+ }
230
+ function rejectLeaseDrainForQuarantine(generation) {
231
+ const failure = getQuarantinedLeaseFailure(generation);
232
+ if (failure === undefined)
233
+ return false;
234
+ const reject = generation.rejectLeaseDrain;
235
+ if (reject === undefined)
236
+ return true;
237
+ generation.settleLeaseDrain = undefined;
238
+ generation.rejectLeaseDrain = undefined;
239
+ generation.retirementDrainQuarantined = true;
240
+ apply(reject, undefined, [failure]);
241
+ return true;
242
+ }
243
+ function throwRetirementHandlerFailures(generation) {
244
+ if (generation.retirementHandlerFailures.length === 0)
245
+ return;
246
+ if (generation.retirementHandlerFailures.length === 1) {
247
+ throw generation.retirementHandlerFailures[0];
248
+ }
249
+ throw new NativeAggregateError(copyArrayForAggregateError(generation.retirementHandlerFailures), "Extension contract generation retirement controls failed");
250
+ }
251
+ function unpublishExactGenerationEntries(generation) {
252
+ forEachMapValue(generation.entries, (entry, name) => {
253
+ if (getMapValue(registeredContracts, name) === entry) {
254
+ deleteMapValue(registeredContracts, name);
255
+ }
256
+ });
257
+ }
258
+ /** Read one raw public registration. */
259
+ export function tryResolveRegisteredContract(name) {
260
+ const scopedResolution = getScopedResolutionState();
261
+ if (scopedResolution === null)
262
+ return undefined;
263
+ if (scopedResolution?.entryOverlay !== undefined) {
264
+ const overlay = scopedResolution.entryOverlay;
265
+ if (!hasSetValue(overlay.entryOverlayShadows, name)) {
266
+ const scopedEntry = getMapValue(overlay.entries, name);
267
+ if (scopedEntry !== undefined)
268
+ return scopedEntry.implementation;
269
+ }
270
+ }
271
+ return getMapValue(registeredContracts, name)?.implementation;
272
+ }
273
+ function assertRetiringGeneration(generation) {
274
+ if (generation.status !== "retiring") {
275
+ throw new NativeError("Contract generation resolution scope requires a retiring generation");
276
+ }
277
+ }
278
+ function createContractGenerationResolutionScope(generation, entryOverlay) {
279
+ return createNullPrototypeRecord({
280
+ entryOverlay,
281
+ resetToken: generation.resetToken,
282
+ active: true,
283
+ });
284
+ }
285
+ function runWithContractGenerationScope(generation, entryOverlay, operation) {
286
+ assertRetiringGeneration(generation);
287
+ const scope = createContractGenerationResolutionScope(generation, entryOverlay);
288
+ try {
289
+ return apply(asyncLocalStorageRun, generationResolutionStorage, [
290
+ scope,
291
+ async () => {
292
+ try {
293
+ return await operation();
294
+ }
295
+ finally {
296
+ scope.active = false;
297
+ }
298
+ },
299
+ ]);
300
+ }
301
+ catch (error) {
302
+ scope.active = false;
303
+ throw error;
304
+ }
305
+ }
306
+ function runWithContractGenerationEpochSync(generation, operation) {
307
+ assertRetiringGeneration(generation);
308
+ const scope = createContractGenerationResolutionScope(generation);
309
+ try {
310
+ return apply(asyncLocalStorageRun, generationResolutionStorage, [scope, operation]);
311
+ }
312
+ finally {
313
+ scope.active = false;
314
+ }
315
+ }
316
+ /**
317
+ * Bind raw contract resolution to a failed candidate during rollback.
318
+ *
319
+ * Failed candidates retain their unpublished staged dependencies. Reset and
320
+ * hook settlement still revoke inherited descendants.
321
+ */
322
+ export function runWithContractGenerationResolution(generation, operation) {
323
+ return runWithContractGenerationScope(generation, generation, operation);
324
+ }
325
+ /**
326
+ * Bind teardown to one registry epoch without overriding current raw entries.
327
+ *
328
+ * Successful teardown keeps the registry's public overwrite semantics while
329
+ * stale or detached work remains unable to cross a reset boundary.
330
+ */
331
+ export function runWithContractGenerationEpoch(generation, operation) {
332
+ return runWithContractGenerationScope(generation, undefined, operation);
333
+ }
334
+ /** Install one unmanaged public registration. */
335
+ export function registerUnmanagedContract(name, implementation) {
336
+ const scope = assertCurrentMutationScope("register");
337
+ setMapValue(registeredContracts, name, createEntry(implementation));
338
+ if (scope?.entryOverlay !== undefined) {
339
+ addSetValue(scope.entryOverlay.entryOverlayShadows, name);
340
+ }
341
+ }
342
+ /** Remove the current public registration without lifecycle coordination. */
343
+ export function unregisterContract(name) {
344
+ const scope = assertCurrentMutationScope("unregister");
345
+ deleteMapValue(registeredContracts, name);
346
+ if (scope?.entryOverlay !== undefined) {
347
+ addSetValue(scope.entryOverlay.entryOverlayShadows, name);
348
+ }
349
+ }
350
+ /**
351
+ * Force-clear the public registry and lifecycle state.
352
+ *
353
+ * This preserves the historical synchronous reset primitive used by tests and
354
+ * composition roots. Normal loader shutdown must use generation retirement.
355
+ */
356
+ export function resetContractRegistry() {
357
+ assertCurrentMutationScope("reset");
358
+ clearMap(registeredContracts);
359
+ activeGeneration = undefined;
360
+ stagingGeneration = undefined;
361
+ failedGenerationUnavailable = false;
362
+ contractRegistryResetToken = createRegistryResetToken();
363
+ }
364
+ /** Start staging one candidate generation without publishing partial entries. */
365
+ export function beginContractGeneration() {
366
+ assertContractGenerationAdmissionAllowed();
367
+ if (stagingGeneration !== undefined) {
368
+ throw new NativeError("Another extension contract generation is already staging");
369
+ }
370
+ const generation = createNullPrototypeRecord({
371
+ resetToken: contractRegistryResetToken,
372
+ status: "staging",
373
+ entries: new NativeMap(),
374
+ entryOverlayShadows: new NativeSet(),
375
+ leases: new NativeSet(),
376
+ retirementHandlerFailures: [],
377
+ retirementNotificationDepth: 0,
378
+ retirementReason: undefined,
379
+ hasRetirementReason: false,
380
+ retirementNotificationStarted: false,
381
+ settleLeaseDrain: undefined,
382
+ rejectLeaseDrain: undefined,
383
+ retirementDrainQuarantined: false,
384
+ retirementPromise: undefined,
385
+ });
386
+ stagingGeneration = generation;
387
+ return generation;
388
+ }
389
+ /** Stage or replace one loader-owned entry inside a candidate generation. */
390
+ export function stageContract(generation, name, implementation) {
391
+ assertNoGenerationTransitionDuringTeardown("stage");
392
+ assertCanonicalNonEmptyString(name, "Contract name");
393
+ if (implementation === undefined) {
394
+ throw new TypeError(`Contract "${name}" implementation must not be undefined`);
395
+ }
396
+ assertStagingGeneration(generation);
397
+ setMapValue(generation.entries, name, createEntry(implementation, generation));
398
+ }
399
+ /** Resolve candidate-local dependencies without publishing the candidate. */
400
+ export function tryResolveContractForGeneration(generation, name) {
401
+ assertCanonicalNonEmptyString(name, "Contract name");
402
+ if (generation.resetToken !== contractRegistryResetToken) {
403
+ throw new NativeError(`Extension contract "${name}" is unavailable after the registry was reset`);
404
+ }
405
+ const staged = getMapValue(generation.entries, name);
406
+ if (staged !== undefined)
407
+ return staged.implementation;
408
+ return tryResolveRegisteredContract(name);
409
+ }
410
+ /** Atomically publish every staged entry and open active-use admission. */
411
+ export function commitContractGeneration(generation) {
412
+ assertNoGenerationTransitionDuringTeardown("commit");
413
+ assertStagingGeneration(generation);
414
+ if (activeGeneration?.status === "active") {
415
+ throw new NativeError("Cannot publish an extension contract generation before the active generation retires");
416
+ }
417
+ forEachMapValue(registeredContracts, (entry) => {
418
+ const owner = entry.generation;
419
+ if (owner !== undefined &&
420
+ owner !== generation &&
421
+ owner.status !== "retired" &&
422
+ owner.status !== "failed") {
423
+ throw new NativeError("Cannot publish an extension contract generation while a prior generation remains owned");
424
+ }
425
+ });
426
+ forEachMapValue(generation.entries, (entry, name) => {
427
+ setMapValue(registeredContracts, name, entry);
428
+ });
429
+ generation.status = "active";
430
+ activeGeneration = generation;
431
+ stagingGeneration = undefined;
432
+ failedGenerationUnavailable = false;
433
+ }
434
+ /**
435
+ * Capture a contract for lifecycle-aware use.
436
+ *
437
+ * Missing is distinct from an unavailable transition: callers may apply their
438
+ * documented fallback only for a stable, genuinely absent registration.
439
+ */
440
+ export function trySnapshotContractForUse(name) {
441
+ assertCanonicalNonEmptyString(name, "Contract name");
442
+ assertNoLifecycleAdmissionDuringTeardown(name);
443
+ if (stagingGeneration !== undefined) {
444
+ throw unavailableDuringTransition(name);
445
+ }
446
+ const entry = getMapValue(registeredContracts, name);
447
+ if (entry !== undefined) {
448
+ const owner = entry.generation;
449
+ if (owner === undefined || owner.status === "active") {
450
+ return freeze({
451
+ implementation: entry.implementation,
452
+ reference: freeze({ name, entry }),
453
+ });
454
+ }
455
+ throw unavailableDuringTransition(name);
456
+ }
457
+ if (failedGenerationUnavailable) {
458
+ throw unavailableDuringTransition(name);
459
+ }
460
+ return undefined;
461
+ }
462
+ /**
463
+ * Capture only a loader-generation-owned contract for security-sensitive use.
464
+ *
465
+ * Ownerless registrations remain available to compatibility consumers through
466
+ * `trySnapshotContractForUse`, but cannot satisfy a contract whose safety
467
+ * depends on retirement fencing and active-use lease drainage.
468
+ */
469
+ export function trySnapshotGenerationOwnedContractForUse(name) {
470
+ const snapshot = trySnapshotContractForUse(name);
471
+ if (snapshot === undefined || snapshot.reference.entry.generation === undefined) {
472
+ return undefined;
473
+ }
474
+ return snapshot;
475
+ }
476
+ /** Acquire active-use ownership immediately before invoking a contract. */
477
+ export function acquireContractLease(reference) {
478
+ assertNoLifecycleAdmissionDuringTeardown(reference.name);
479
+ const entry = reference.entry;
480
+ const generation = entry.generation;
481
+ if (generation === undefined) {
482
+ return freeze({
483
+ setRetirementHandler() { },
484
+ quarantine() { },
485
+ release() { },
486
+ });
487
+ }
488
+ if (stagingGeneration !== undefined ||
489
+ generation.status !== "active" ||
490
+ getMapValue(registeredContracts, reference.name) !== entry) {
491
+ throw unavailableDuringTransition(reference.name);
492
+ }
493
+ const record = createNullPrototypeRecord({
494
+ released: false,
495
+ quarantined: false,
496
+ quarantineFailure: undefined,
497
+ retirementNotified: false,
498
+ retirementHandler: undefined,
499
+ });
500
+ addSetValue(generation.leases, record);
501
+ let retirementHandlerRegistered = false;
502
+ return freeze({
503
+ setRetirementHandler(handler) {
504
+ if (typeof handler !== "function") {
505
+ throw new TypeError("Contract lease retirement handler must be a function");
506
+ }
507
+ if (record.released) {
508
+ throw new NativeError("Cannot configure a released contract generation lease");
509
+ }
510
+ if (retirementHandlerRegistered) {
511
+ throw new NativeError("Contract generation lease already has a retirement handler");
512
+ }
513
+ retirementHandlerRegistered = true;
514
+ record.retirementHandler = handler;
515
+ notifyRetirement(generation, record);
516
+ },
517
+ quarantine() {
518
+ if (record.released || record.quarantined)
519
+ return;
520
+ const failure = new NativeError(`Extension contract generation is quarantined because "${reference.name}" has an unsettled use`);
521
+ record.quarantined = true;
522
+ record.quarantineFailure = failure;
523
+ if (generation.status === "active") {
524
+ sealContractGeneration(generation, failure);
525
+ }
526
+ rejectLeaseDrainForQuarantine(generation);
527
+ },
528
+ release() {
529
+ if (record.released)
530
+ return;
531
+ if (!deleteSetValue(generation.leases, record)) {
532
+ throw new NativeError("Contract generation lease record is missing");
533
+ }
534
+ record.released = true;
535
+ if (record.quarantined &&
536
+ generation.retirementDrainQuarantined &&
537
+ getQuarantinedLeaseFailure(generation) === undefined) {
538
+ generation.retirementPromise = undefined;
539
+ generation.retirementDrainQuarantined = false;
540
+ }
541
+ finishLeaseDrain(generation);
542
+ },
543
+ });
544
+ }
545
+ /**
546
+ * Close admission synchronously before contexts or other generation-owned
547
+ * resources begin revocation.
548
+ */
549
+ export function sealContractGeneration(generation, reason = new NativeError("Extension contract generation was retired")) {
550
+ if (generation.status === "retired" || generation.status === "failed") {
551
+ return;
552
+ }
553
+ if (generation.status === "retiring") {
554
+ return;
555
+ }
556
+ generation.status = "retiring";
557
+ if (activeGeneration === generation)
558
+ activeGeneration = undefined;
559
+ generation.retirementReason = reason;
560
+ generation.hasRetirementReason = true;
561
+ }
562
+ /**
563
+ * Notify active uses synchronously, then await release or reject if an active
564
+ * lease has quarantined the generation. A drain may be retried after release.
565
+ */
566
+ export function drainContractGeneration(generation) {
567
+ if (generation.status === "retired" || generation.status === "failed") {
568
+ return createResolvedPromise();
569
+ }
570
+ if (generation.status !== "retiring") {
571
+ throw new NativeError("Contract generation must be sealed before it can drain");
572
+ }
573
+ if (generation.retirementPromise !== undefined) {
574
+ return generation.retirementPromise;
575
+ }
576
+ const retirement = createPinnedPromise((resolve, reject) => {
577
+ generation.settleLeaseDrain = () => {
578
+ try {
579
+ throwRetirementHandlerFailures(generation);
580
+ resolve();
581
+ }
582
+ catch (error) {
583
+ reject(error);
584
+ }
585
+ };
586
+ generation.rejectLeaseDrain = reject;
587
+ });
588
+ generation.retirementPromise = retirement;
589
+ generation.retirementNotificationStarted = true;
590
+ forEachSetValue(generation.leases, (record) => {
591
+ notifyRetirement(generation, record);
592
+ });
593
+ if (!rejectLeaseDrainForQuarantine(generation)) {
594
+ finishLeaseDrain(generation);
595
+ }
596
+ return retirement;
597
+ }
598
+ /** Whether every admitted use has released before extension teardown begins. */
599
+ export function isContractGenerationDrained(generation) {
600
+ return getSetSize(generation.leases) === 0;
601
+ }
602
+ /** Complete a successful teardown and remove only this generation's entries. */
603
+ export function completeContractGenerationRetirement(generation) {
604
+ if (generation.status !== "retiring") {
605
+ throw new NativeError("Contract generation must retire before teardown can complete");
606
+ }
607
+ if (!isContractGenerationDrained(generation)) {
608
+ throw new NativeError("Contract generation still has active leases");
609
+ }
610
+ const ownsCurrentRegistry = generation.resetToken === contractRegistryResetToken;
611
+ if (ownsCurrentRegistry) {
612
+ unpublishExactGenerationEntries(generation);
613
+ }
614
+ generation.status = "retired";
615
+ if (ownsCurrentRegistry) {
616
+ if (activeGeneration === generation)
617
+ activeGeneration = undefined;
618
+ if (stagingGeneration === generation)
619
+ stagingGeneration = undefined;
620
+ }
621
+ }
622
+ /**
623
+ * Finish a failed candidate. Absence remains fail-closed until a later
624
+ * generation commits successfully or the low-level registry is reset.
625
+ */
626
+ export function failContractGeneration(generation) {
627
+ if (!isContractGenerationDrained(generation)) {
628
+ throw new NativeError("Failed contract generation still has active leases");
629
+ }
630
+ const ownsCurrentRegistry = generation.resetToken === contractRegistryResetToken;
631
+ if (ownsCurrentRegistry) {
632
+ unpublishExactGenerationEntries(generation);
633
+ }
634
+ generation.status = "failed";
635
+ if (ownsCurrentRegistry) {
636
+ if (activeGeneration === generation)
637
+ activeGeneration = undefined;
638
+ if (stagingGeneration === generation)
639
+ stagingGeneration = undefined;
640
+ failedGenerationUnavailable = activeGeneration === undefined;
641
+ }
642
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Contract registry — runtime resolution of extension-provided implementations.
3
+ *
4
+ * @module extensions/contracts
5
+ */
6
+ /** Resolve path segments to an absolute path. */
7
+ export declare function resolve<T>(name: string): T;
8
+ /** Try to resolve. */
9
+ export declare function tryResolve<T>(name: string): T | undefined;
10
+ /** Register. */
11
+ export declare function register<T>(name: string, impl: T): void;
12
+ /** Unregister. */
13
+ export declare function unregister(name: string): void;
14
+ /** Reset. */
15
+ export declare function reset(): void;
16
+ //# sourceMappingURL=contracts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contracts.d.ts","sourceRoot":"","sources":["../../../src/src/extensions/contracts.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAYH,iDAAiD;AACjD,wBAAgB,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,CAa1C;AAED,sBAAsB;AACtB,wBAAgB,UAAU,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS,CAGzD;AAED,gBAAgB;AAChB,wBAAgB,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,GAAG,IAAI,CAMvD;AAED,kBAAkB;AAClB,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAG7C;AAED,aAAa;AACb,wBAAgB,KAAK,IAAI,IAAI,CAE5B"}