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/README.md +563 -1
- package/dist/index.cjs +85 -38
- package/dist/index.cjs.map +3 -3
- package/dist/index.mjs +85 -38
- package/dist/index.mjs.map +3 -3
- package/dist/src/app-context/app-context.d.ts +14 -3
- package/package.json +1 -1
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
|
|
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 (
|
|
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.
|
|
1308
|
-
this.
|
|
1309
|
-
this.
|
|
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 &&
|
|
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.
|
|
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.
|
|
1338
|
-
this.createdEntries?.set(record, entry);
|
|
1401
|
+
this.recordEntries.set(record, entry);
|
|
1339
1402
|
this.registry.set(record.classRef, entry);
|
|
1340
|
-
this.
|
|
1341
|
-
if (entry.inst
|
|
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 (
|
|
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
|
-
|
|
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
|
-
|
|
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
|
}
|