nfkit 1.0.35 → 1.0.36

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
@@ -1249,11 +1249,11 @@ var observeDiff = (obj, cb) => {
1249
1249
  // src/memorize.ts
1250
1250
  var Memorize = () => {
1251
1251
  const cache = /* @__PURE__ */ new WeakMap();
1252
- const isPromiseLike = (v) => v != null && typeof v.then === "function" && typeof v.catch === "function";
1252
+ const isPromiseLike2 = (v) => v != null && typeof v.then === "function" && typeof v.catch === "function";
1253
1253
  const getOrSet = (instance, compute) => {
1254
1254
  if (cache.has(instance)) return cache.get(instance);
1255
1255
  const result = compute();
1256
- if (isPromiseLike(result)) {
1256
+ if (isPromiseLike2(result)) {
1257
1257
  const wrapped = result.catch((err) => {
1258
1258
  cache.delete(instance);
1259
1259
  throw err;
@@ -1297,6 +1297,7 @@ var getMethodDescriptor = (cls, key) => {
1297
1297
  }
1298
1298
  return void 0;
1299
1299
  };
1300
+ var isPromiseLike = (value) => !!value && typeof value.then === "function";
1300
1301
  var AppContextCore = class {
1301
1302
  constructor() {
1302
1303
  this.provideRecords = [];
@@ -1304,22 +1305,85 @@ var AppContextCore = class {
1304
1305
  this.objectSteps = [];
1305
1306
  this.started = false;
1306
1307
  this.starting = false;
1307
- this.startingEntries = null;
1308
- this.createdRecords = null;
1309
- this.createdEntries = null;
1308
+ this.settleCursor = 0;
1309
+ this.recordEntries = /* @__PURE__ */ new Map();
1310
+ this.pendingInitQueue = [];
1311
+ this.pendingInitSet = /* @__PURE__ */ new Set();
1312
+ this.initializedEntries = /* @__PURE__ */ new Set();
1310
1313
  this.loadingRecords = /* @__PURE__ */ new Set();
1314
+ this.settlementChain = Promise.resolve();
1315
+ this.settlementError = null;
1316
+ this.settling = false;
1317
+ }
1318
+ assertSettlementHealthy() {
1319
+ if (this.settlementError) {
1320
+ throw this.settlementError;
1321
+ }
1322
+ }
1323
+ enqueueInit(entry) {
1324
+ if (this.initializedEntries.has(entry) || this.pendingInitSet.has(entry)) {
1325
+ return;
1326
+ }
1327
+ this.pendingInitSet.add(entry);
1328
+ this.pendingInitQueue.push(entry);
1329
+ }
1330
+ async constructPendingRecords() {
1331
+ while (this.settleCursor < this.provideRecords.length) {
1332
+ const record = this.provideRecords[this.settleCursor];
1333
+ this.settleCursor += 1;
1334
+ await this.createEntryFromRecord(record);
1335
+ }
1336
+ }
1337
+ async settlePending() {
1338
+ await this.constructPendingRecords();
1339
+ while (this.pendingInitQueue.length > 0) {
1340
+ const entry = this.pendingInitQueue.shift();
1341
+ this.pendingInitSet.delete(entry);
1342
+ if (this.initializedEntries.has(entry)) {
1343
+ continue;
1344
+ }
1345
+ const inst = await entry.inst;
1346
+ entry.inst = inst;
1347
+ if (inst && typeof inst.init === "function") {
1348
+ await inst.init();
1349
+ }
1350
+ this.initializedEntries.add(entry);
1351
+ const remaining = this.pendingInitQueue.splice(0);
1352
+ await this.constructPendingRecords();
1353
+ this.pendingInitQueue.push(...remaining);
1354
+ }
1355
+ }
1356
+ scheduleSettlement() {
1357
+ const run = async () => {
1358
+ this.assertSettlementHealthy();
1359
+ this.settling = true;
1360
+ try {
1361
+ await this.settlePending();
1362
+ } catch (error) {
1363
+ this.settlementError = error;
1364
+ throw error;
1365
+ } finally {
1366
+ this.settling = false;
1367
+ }
1368
+ };
1369
+ const task = this.settlementChain.then(run, run);
1370
+ this.settlementChain = task.catch(() => void 0);
1371
+ return task;
1372
+ }
1373
+ triggerSettlement() {
1374
+ void this.scheduleSettlement();
1311
1375
  }
1312
1376
  findProvideRecord(key) {
1313
1377
  for (let i = 0; i < this.provideRecords.length; i += 1) {
1314
1378
  const record = this.provideRecords[i];
1315
- if (record.classRef === key && (!this.createdRecords || !this.createdRecords.has(record))) {
1379
+ if (record.classRef === key && !this.recordEntries.has(record)) {
1316
1380
  return record;
1317
1381
  }
1318
1382
  }
1319
1383
  return void 0;
1320
1384
  }
1321
1385
  createEntryFromRecord(record) {
1322
- const existing = this.createdEntries?.get(record);
1386
+ const existing = this.recordEntries.get(record);
1323
1387
  if (existing) {
1324
1388
  return existing;
1325
1389
  }
@@ -1334,11 +1398,10 @@ var AppContextCore = class {
1334
1398
  classRef: record.classRef,
1335
1399
  inst: record.factory(this)
1336
1400
  };
1337
- this.createdRecords?.add(record);
1338
- this.createdEntries?.set(record, entry);
1401
+ this.recordEntries.set(record, entry);
1339
1402
  this.registry.set(record.classRef, entry);
1340
- this.startingEntries?.push(entry);
1341
- if (entry.inst?.then && typeof entry.inst.then === "function") {
1403
+ this.enqueueInit(entry);
1404
+ if (isPromiseLike(entry.inst)) {
1342
1405
  return entry.inst.then((resolvedInst) => {
1343
1406
  entry.inst = resolvedInst;
1344
1407
  return entry;
@@ -1350,6 +1413,7 @@ var AppContextCore = class {
1350
1413
  }
1351
1414
  }
1352
1415
  provide(cls, ...args) {
1416
+ this.assertSettlementHealthy();
1353
1417
  const last = args[args.length - 1];
1354
1418
  const hasOptions = !!last && typeof last === "object" && ("provide" in last || "merge" in last || "useValue" in last || "useFactory" in last || "useClass" in last);
1355
1419
  const options = hasOptions ? last : void 0;
@@ -1414,11 +1478,12 @@ var AppContextCore = class {
1414
1478
  return this;
1415
1479
  }
1416
1480
  get(cls) {
1481
+ this.assertSettlementHealthy();
1417
1482
  let key = cls;
1418
1483
  if (!this.registry.has(key) && typeof cls === "function" && !cls.prototype) {
1419
1484
  key = cls();
1420
1485
  }
1421
- if (!this.registry.has(key) && this.starting) {
1486
+ if (!this.registry.has(key) && (this.starting || this.settling)) {
1422
1487
  const record = this.findProvideRecord(key);
1423
1488
  if (record) {
1424
1489
  this.createEntryFromRecord(record);
@@ -1434,14 +1499,10 @@ var AppContextCore = class {
1434
1499
  return await this.get(cls);
1435
1500
  }
1436
1501
  use(...ctxes) {
1502
+ this.assertSettlementHealthy();
1437
1503
  for (const ctx of ctxes) {
1438
1504
  const other = ctx;
1439
- if (this.started && !other?.started) {
1440
- throw new Error(
1441
- "Cannot use an unstarted context into a started context."
1442
- );
1443
- }
1444
- if (Array.isArray(other?.provideRecords)) {
1505
+ if (Array.isArray(other?.provideRecords) && !other?.started) {
1445
1506
  this.provideRecords.push(...other.provideRecords);
1446
1507
  }
1447
1508
  if (Array.isArray(other?.objectSteps)) {
@@ -1461,37 +1522,23 @@ var AppContextCore = class {
1461
1522
  return this;
1462
1523
  }
1463
1524
  define() {
1525
+ this.assertSettlementHealthy();
1526
+ if (this.started && !this.starting) {
1527
+ this.triggerSettlement();
1528
+ }
1464
1529
  return this;
1465
1530
  }
1466
1531
  async start() {
1467
1532
  if (this.started) {
1468
1533
  return this;
1469
1534
  }
1470
- const startedEntries = [];
1471
- const preloadedKeys = new Set(this.registry.keys());
1535
+ this.assertSettlementHealthy();
1472
1536
  this.starting = true;
1473
- this.startingEntries = startedEntries;
1474
- this.createdRecords = /* @__PURE__ */ new Set();
1475
- this.createdEntries = /* @__PURE__ */ new Map();
1476
1537
  try {
1477
- for (const record of this.provideRecords) {
1478
- if (preloadedKeys.has(record.classRef)) {
1479
- continue;
1480
- }
1481
- await this.createEntryFromRecord(record);
1482
- }
1483
- for (const entry of startedEntries) {
1484
- const inst = entry.inst;
1485
- if (inst && typeof inst.init === "function") {
1486
- await inst.init();
1487
- }
1488
- }
1538
+ await this.scheduleSettlement();
1489
1539
  this.started = true;
1490
1540
  return this;
1491
1541
  } finally {
1492
- this.createdEntries = null;
1493
- this.createdRecords = null;
1494
- this.startingEntries = null;
1495
1542
  this.starting = false;
1496
1543
  }
1497
1544
  }