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.cjs CHANGED
@@ -1302,7 +1302,84 @@ var AppContextCore = class {
1302
1302
  this.provideRecords = [];
1303
1303
  this.registry = /* @__PURE__ */ new Map();
1304
1304
  this.objectSteps = [];
1305
+ this.parentContexts = /* @__PURE__ */ new Set();
1305
1306
  this.started = false;
1307
+ this.starting = false;
1308
+ this.startingEntries = null;
1309
+ this.createdRecords = null;
1310
+ this.createdEntries = null;
1311
+ this.loadingRecords = /* @__PURE__ */ new Set();
1312
+ }
1313
+ findProvideRecord(key) {
1314
+ for (let i = 0; i < this.provideRecords.length; i += 1) {
1315
+ const record = this.provideRecords[i];
1316
+ if (record.classRef === key && (!this.createdRecords || !this.createdRecords.has(record))) {
1317
+ return record;
1318
+ }
1319
+ }
1320
+ return void 0;
1321
+ }
1322
+ createEntryFromRecord(record) {
1323
+ const existing = this.createdEntries?.get(record);
1324
+ if (existing) {
1325
+ return existing;
1326
+ }
1327
+ if (this.loadingRecords.has(record)) {
1328
+ throw new Error(
1329
+ `Circular dependency detected while providing: ${record.classRef?.name ?? "UnknownService"}`
1330
+ );
1331
+ }
1332
+ this.loadingRecords.add(record);
1333
+ try {
1334
+ const entry = {
1335
+ classRef: record.classRef,
1336
+ inst: record.factory(this)
1337
+ };
1338
+ this.createdRecords?.add(record);
1339
+ this.createdEntries?.set(record, entry);
1340
+ this.registry.set(record.classRef, entry);
1341
+ this.startingEntries?.push(entry);
1342
+ return entry;
1343
+ } finally {
1344
+ this.loadingRecords.delete(record);
1345
+ }
1346
+ }
1347
+ applyUsedContext(other) {
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
+ }
1364
+ }
1365
+ hasStartedInParentChain(visited = /* @__PURE__ */ new Set()) {
1366
+ if (visited.has(this)) return false;
1367
+ visited.add(this);
1368
+ if (this.started) return true;
1369
+ for (const parent of this.parentContexts) {
1370
+ if (parent.hasStartedInParentChain(visited)) {
1371
+ return true;
1372
+ }
1373
+ }
1374
+ return false;
1375
+ }
1376
+ propagateUsedContextToParents(other, visited = /* @__PURE__ */ new Set()) {
1377
+ if (visited.has(this)) return;
1378
+ visited.add(this);
1379
+ for (const parent of this.parentContexts) {
1380
+ parent.applyUsedContext(other);
1381
+ parent.propagateUsedContextToParents(other, visited);
1382
+ }
1306
1383
  }
1307
1384
  provide(cls, ...args) {
1308
1385
  const last = args[args.length - 1];
@@ -1373,6 +1450,12 @@ var AppContextCore = class {
1373
1450
  if (!this.registry.has(key) && typeof cls === "function" && !cls.prototype) {
1374
1451
  key = cls();
1375
1452
  }
1453
+ if (!this.registry.has(key) && this.starting) {
1454
+ const record = this.findProvideRecord(key);
1455
+ if (record) {
1456
+ this.createEntryFromRecord(record);
1457
+ }
1458
+ }
1376
1459
  if (!this.registry.has(key)) {
1377
1460
  throw new Error(`Service not provided: ${key?.name ?? cls.name}`);
1378
1461
  }
@@ -1388,27 +1471,14 @@ var AppContextCore = class {
1388
1471
  use(...ctxes) {
1389
1472
  for (const ctx of ctxes) {
1390
1473
  const other = ctx;
1391
- if (this.started && !other?.started) {
1474
+ if (this.hasStartedInParentChain() && !other?.started) {
1392
1475
  throw new Error(
1393
1476
  "Cannot use an unstarted context into a started context."
1394
1477
  );
1395
1478
  }
1396
- if (Array.isArray(other?.provideRecords)) {
1397
- this.provideRecords.push(...other.provideRecords);
1398
- }
1399
- if (Array.isArray(other?.objectSteps)) {
1400
- this.objectSteps.push(...other.objectSteps);
1401
- for (const step of other.objectSteps) {
1402
- step(this);
1403
- }
1404
- }
1405
- if (other?.started) {
1406
- if (other?.registry instanceof Map) {
1407
- for (const [key, value] of other.registry.entries()) {
1408
- this.registry.set(key, value);
1409
- }
1410
- }
1411
- }
1479
+ this.applyUsedContext(other);
1480
+ other.parentContexts.add(this);
1481
+ this.propagateUsedContextToParents(other);
1412
1482
  }
1413
1483
  return this;
1414
1484
  }
@@ -1421,31 +1491,36 @@ var AppContextCore = class {
1421
1491
  }
1422
1492
  const startedEntries = [];
1423
1493
  const preloadedKeys = new Set(this.registry.keys());
1424
- for (const record of this.provideRecords) {
1425
- if (preloadedKeys.has(record.classRef)) {
1426
- continue;
1494
+ this.starting = true;
1495
+ this.startingEntries = startedEntries;
1496
+ this.createdRecords = /* @__PURE__ */ new Set();
1497
+ this.createdEntries = /* @__PURE__ */ new Map();
1498
+ try {
1499
+ for (const record of this.provideRecords) {
1500
+ if (preloadedKeys.has(record.classRef)) {
1501
+ continue;
1502
+ }
1503
+ this.createEntryFromRecord(record);
1427
1504
  }
1428
- const inst = record.factory(this);
1429
- const entry = {
1430
- classRef: record.classRef,
1431
- inst
1432
- };
1433
- this.registry.set(record.classRef, entry);
1434
- startedEntries.push(entry);
1435
- }
1436
- for (const entry of startedEntries) {
1437
- if (entry.inst && typeof entry.inst.then === "function") {
1438
- entry.inst = await entry.inst;
1505
+ for (const entry of startedEntries) {
1506
+ if (entry.inst && typeof entry.inst.then === "function") {
1507
+ entry.inst = await entry.inst;
1508
+ }
1439
1509
  }
1440
- }
1441
- for (const entry of startedEntries) {
1442
- const inst = entry.inst;
1443
- if (inst && typeof inst.init === "function") {
1444
- await inst.init();
1510
+ for (const entry of startedEntries) {
1511
+ const inst = entry.inst;
1512
+ if (inst && typeof inst.init === "function") {
1513
+ await inst.init();
1514
+ }
1445
1515
  }
1516
+ this.started = true;
1517
+ return this;
1518
+ } finally {
1519
+ this.createdEntries = null;
1520
+ this.createdRecords = null;
1521
+ this.startingEntries = null;
1522
+ this.starting = false;
1446
1523
  }
1447
- this.started = true;
1448
- return this;
1449
1524
  }
1450
1525
  };
1451
1526
  var createAppContext = () => new AppContextCore();