nfkit 1.0.29 → 1.0.31

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1254,7 +1254,84 @@ var AppContextCore = class {
1254
1254
  this.provideRecords = [];
1255
1255
  this.registry = /* @__PURE__ */ new Map();
1256
1256
  this.objectSteps = [];
1257
+ this.parentContexts = /* @__PURE__ */ new Set();
1257
1258
  this.started = false;
1259
+ this.starting = false;
1260
+ this.startingEntries = null;
1261
+ this.createdRecords = null;
1262
+ this.createdEntries = null;
1263
+ this.loadingRecords = /* @__PURE__ */ new Set();
1264
+ }
1265
+ findProvideRecord(key) {
1266
+ for (let i = 0; i < this.provideRecords.length; i += 1) {
1267
+ const record = this.provideRecords[i];
1268
+ if (record.classRef === key && (!this.createdRecords || !this.createdRecords.has(record))) {
1269
+ return record;
1270
+ }
1271
+ }
1272
+ return void 0;
1273
+ }
1274
+ createEntryFromRecord(record) {
1275
+ const existing = this.createdEntries?.get(record);
1276
+ if (existing) {
1277
+ return existing;
1278
+ }
1279
+ if (this.loadingRecords.has(record)) {
1280
+ throw new Error(
1281
+ `Circular dependency detected while providing: ${record.classRef?.name ?? "UnknownService"}`
1282
+ );
1283
+ }
1284
+ this.loadingRecords.add(record);
1285
+ try {
1286
+ const entry = {
1287
+ classRef: record.classRef,
1288
+ inst: record.factory(this)
1289
+ };
1290
+ this.createdRecords?.add(record);
1291
+ this.createdEntries?.set(record, entry);
1292
+ this.registry.set(record.classRef, entry);
1293
+ this.startingEntries?.push(entry);
1294
+ return entry;
1295
+ } finally {
1296
+ this.loadingRecords.delete(record);
1297
+ }
1298
+ }
1299
+ applyUsedContext(other) {
1300
+ if (Array.isArray(other?.provideRecords)) {
1301
+ this.provideRecords.push(...other.provideRecords);
1302
+ }
1303
+ if (Array.isArray(other?.objectSteps)) {
1304
+ this.objectSteps.push(...other.objectSteps);
1305
+ for (const step of other.objectSteps) {
1306
+ step(this);
1307
+ }
1308
+ }
1309
+ if (other?.started) {
1310
+ if (other?.registry instanceof Map) {
1311
+ for (const [key, value] of other.registry.entries()) {
1312
+ this.registry.set(key, value);
1313
+ }
1314
+ }
1315
+ }
1316
+ }
1317
+ hasStartedInParentChain(visited = /* @__PURE__ */ new Set()) {
1318
+ if (visited.has(this)) return false;
1319
+ visited.add(this);
1320
+ if (this.started) return true;
1321
+ for (const parent of this.parentContexts) {
1322
+ if (parent.hasStartedInParentChain(visited)) {
1323
+ return true;
1324
+ }
1325
+ }
1326
+ return false;
1327
+ }
1328
+ propagateUsedContextToParents(other, visited = /* @__PURE__ */ new Set()) {
1329
+ if (visited.has(this)) return;
1330
+ visited.add(this);
1331
+ for (const parent of this.parentContexts) {
1332
+ parent.applyUsedContext(other);
1333
+ parent.propagateUsedContextToParents(other, visited);
1334
+ }
1258
1335
  }
1259
1336
  provide(cls, ...args) {
1260
1337
  const last = args[args.length - 1];
@@ -1325,6 +1402,12 @@ var AppContextCore = class {
1325
1402
  if (!this.registry.has(key) && typeof cls === "function" && !cls.prototype) {
1326
1403
  key = cls();
1327
1404
  }
1405
+ if (!this.registry.has(key) && this.starting) {
1406
+ const record = this.findProvideRecord(key);
1407
+ if (record) {
1408
+ this.createEntryFromRecord(record);
1409
+ }
1410
+ }
1328
1411
  if (!this.registry.has(key)) {
1329
1412
  throw new Error(`Service not provided: ${key?.name ?? cls.name}`);
1330
1413
  }
@@ -1340,27 +1423,14 @@ var AppContextCore = class {
1340
1423
  use(...ctxes) {
1341
1424
  for (const ctx of ctxes) {
1342
1425
  const other = ctx;
1343
- if (this.started && !other?.started) {
1426
+ if (this.hasStartedInParentChain() && !other?.started) {
1344
1427
  throw new Error(
1345
1428
  "Cannot use an unstarted context into a started context."
1346
1429
  );
1347
1430
  }
1348
- if (Array.isArray(other?.provideRecords)) {
1349
- this.provideRecords.push(...other.provideRecords);
1350
- }
1351
- if (Array.isArray(other?.objectSteps)) {
1352
- this.objectSteps.push(...other.objectSteps);
1353
- for (const step of other.objectSteps) {
1354
- step(this);
1355
- }
1356
- }
1357
- if (other?.started) {
1358
- if (other?.registry instanceof Map) {
1359
- for (const [key, value] of other.registry.entries()) {
1360
- this.registry.set(key, value);
1361
- }
1362
- }
1363
- }
1431
+ this.applyUsedContext(other);
1432
+ other.parentContexts.add(this);
1433
+ this.propagateUsedContextToParents(other);
1364
1434
  }
1365
1435
  return this;
1366
1436
  }
@@ -1373,31 +1443,36 @@ var AppContextCore = class {
1373
1443
  }
1374
1444
  const startedEntries = [];
1375
1445
  const preloadedKeys = new Set(this.registry.keys());
1376
- for (const record of this.provideRecords) {
1377
- if (preloadedKeys.has(record.classRef)) {
1378
- continue;
1446
+ this.starting = true;
1447
+ this.startingEntries = startedEntries;
1448
+ this.createdRecords = /* @__PURE__ */ new Set();
1449
+ this.createdEntries = /* @__PURE__ */ new Map();
1450
+ try {
1451
+ for (const record of this.provideRecords) {
1452
+ if (preloadedKeys.has(record.classRef)) {
1453
+ continue;
1454
+ }
1455
+ this.createEntryFromRecord(record);
1379
1456
  }
1380
- const inst = record.factory(this);
1381
- const entry = {
1382
- classRef: record.classRef,
1383
- inst
1384
- };
1385
- this.registry.set(record.classRef, entry);
1386
- startedEntries.push(entry);
1387
- }
1388
- for (const entry of startedEntries) {
1389
- if (entry.inst && typeof entry.inst.then === "function") {
1390
- entry.inst = await entry.inst;
1457
+ for (const entry of startedEntries) {
1458
+ if (entry.inst && typeof entry.inst.then === "function") {
1459
+ entry.inst = await entry.inst;
1460
+ }
1391
1461
  }
1392
- }
1393
- for (const entry of startedEntries) {
1394
- const inst = entry.inst;
1395
- if (inst && typeof inst.init === "function") {
1396
- await inst.init();
1462
+ for (const entry of startedEntries) {
1463
+ const inst = entry.inst;
1464
+ if (inst && typeof inst.init === "function") {
1465
+ await inst.init();
1466
+ }
1397
1467
  }
1468
+ this.started = true;
1469
+ return this;
1470
+ } finally {
1471
+ this.createdEntries = null;
1472
+ this.createdRecords = null;
1473
+ this.startingEntries = null;
1474
+ this.starting = false;
1398
1475
  }
1399
- this.started = true;
1400
- return this;
1401
1476
  }
1402
1477
  };
1403
1478
  var createAppContext = () => new AppContextCore();