nfkit 1.0.25 → 1.0.27
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 +52 -146
- package/dist/index.cjs.map +4 -4
- package/dist/index.mjs +52 -146
- package/dist/index.mjs.map +4 -4
- package/dist/src/app-context/app-context.d.ts +8 -15
- package/package.json +1 -1
- package/dist/src/app-context/promise-utils.d.ts +0 -20
package/dist/index.cjs
CHANGED
|
@@ -1247,11 +1247,11 @@ var observeDiff = (obj, cb) => {
|
|
|
1247
1247
|
// src/memorize.ts
|
|
1248
1248
|
var Memorize = () => {
|
|
1249
1249
|
const cache = /* @__PURE__ */ new WeakMap();
|
|
1250
|
-
const
|
|
1250
|
+
const isPromiseLike = (v) => v != null && typeof v.then === "function" && typeof v.catch === "function";
|
|
1251
1251
|
const getOrSet = (instance, compute) => {
|
|
1252
1252
|
if (cache.has(instance)) return cache.get(instance);
|
|
1253
1253
|
const result = compute();
|
|
1254
|
-
if (
|
|
1254
|
+
if (isPromiseLike(result)) {
|
|
1255
1255
|
const wrapped = result.catch((err) => {
|
|
1256
1256
|
cache.delete(instance);
|
|
1257
1257
|
throw err;
|
|
@@ -1285,56 +1285,7 @@ var makeArray = (value) => {
|
|
|
1285
1285
|
return Array.isArray(value) ? value : [value];
|
|
1286
1286
|
};
|
|
1287
1287
|
|
|
1288
|
-
// src/app-context/promise-utils.ts
|
|
1289
|
-
var promiseStates = /* @__PURE__ */ new WeakMap();
|
|
1290
|
-
var isPromiseLike = (value) => !!value && typeof value.then === "function";
|
|
1291
|
-
var trackPromise = (promise) => {
|
|
1292
|
-
const existing = promiseStates.get(promise);
|
|
1293
|
-
if (existing) return existing;
|
|
1294
|
-
const state = { status: "pending" };
|
|
1295
|
-
promiseStates.set(promise, state);
|
|
1296
|
-
promise.then(
|
|
1297
|
-
(value) => {
|
|
1298
|
-
state.status = "fulfilled";
|
|
1299
|
-
state.value = value;
|
|
1300
|
-
},
|
|
1301
|
-
(error) => {
|
|
1302
|
-
state.status = "rejected";
|
|
1303
|
-
state.error = error;
|
|
1304
|
-
}
|
|
1305
|
-
);
|
|
1306
|
-
return state;
|
|
1307
|
-
};
|
|
1308
|
-
var wrapMaybePromise = (value, options) => {
|
|
1309
|
-
if (!isPromiseLike(value)) return value;
|
|
1310
|
-
const promise = Promise.resolve(value);
|
|
1311
|
-
const state = trackPromise(promise);
|
|
1312
|
-
if (state.status === "fulfilled") return state.value;
|
|
1313
|
-
if (state.status === "rejected") throw state.error;
|
|
1314
|
-
return dualizeAny(
|
|
1315
|
-
() => {
|
|
1316
|
-
const current = trackPromise(promise);
|
|
1317
|
-
if (current.status === "fulfilled") return current.value;
|
|
1318
|
-
if (current.status === "rejected") throw current.error;
|
|
1319
|
-
throwDualPending();
|
|
1320
|
-
},
|
|
1321
|
-
() => promise,
|
|
1322
|
-
{
|
|
1323
|
-
// Intentionally hide strict method return type here.
|
|
1324
|
-
asyncMethods: Array.from(options?.methodKeys ?? [])
|
|
1325
|
-
}
|
|
1326
|
-
);
|
|
1327
|
-
};
|
|
1328
|
-
var createAsyncMethod = (inst, key) => (...args) => Promise.resolve(inst).then((resolved) => {
|
|
1329
|
-
const fn = resolved?.[key];
|
|
1330
|
-
if (typeof fn !== "function") {
|
|
1331
|
-
throw new TypeError("Target method is not a function");
|
|
1332
|
-
}
|
|
1333
|
-
return fn.apply(resolved, args);
|
|
1334
|
-
});
|
|
1335
|
-
|
|
1336
1288
|
// src/app-context/app-context.ts
|
|
1337
|
-
var ProvidePrefix = "provide:";
|
|
1338
1289
|
var getMethodDescriptor = (cls, key) => {
|
|
1339
1290
|
let proto = cls.prototype;
|
|
1340
1291
|
while (proto && proto !== Object.prototype) {
|
|
@@ -1344,52 +1295,24 @@ var getMethodDescriptor = (cls, key) => {
|
|
|
1344
1295
|
}
|
|
1345
1296
|
return void 0;
|
|
1346
1297
|
};
|
|
1347
|
-
var flushPendingSets = (entry) => {
|
|
1348
|
-
if (isPromiseLike(entry.inst)) return;
|
|
1349
|
-
if (!entry.pendingSets.length) return;
|
|
1350
|
-
for (const item of entry.pendingSets) {
|
|
1351
|
-
entry.inst[item.key] = item.value;
|
|
1352
|
-
}
|
|
1353
|
-
entry.pendingSets.length = 0;
|
|
1354
|
-
};
|
|
1355
|
-
var resolveEntryIfNeeded = async (entry) => {
|
|
1356
|
-
if (isPromiseLike(entry.inst)) {
|
|
1357
|
-
entry.inst = await entry.inst;
|
|
1358
|
-
}
|
|
1359
|
-
flushPendingSets(entry);
|
|
1360
|
-
return entry.inst;
|
|
1361
|
-
};
|
|
1362
1298
|
var AppContextCore = class {
|
|
1363
1299
|
constructor() {
|
|
1300
|
+
this.provideRecords = [];
|
|
1364
1301
|
this.registry = /* @__PURE__ */ new Map();
|
|
1365
|
-
this.loadSeq = [];
|
|
1366
1302
|
this.objectSteps = [];
|
|
1303
|
+
this.started = false;
|
|
1367
1304
|
}
|
|
1368
1305
|
provide(cls, ...args) {
|
|
1369
1306
|
const last = args[args.length - 1];
|
|
1370
1307
|
const hasOptions = !!last && typeof last === "object" && ("provide" in last || "merge" in last || "useValue" in last || "useFactory" in last || "useClass" in last);
|
|
1371
1308
|
const options = hasOptions ? last : void 0;
|
|
1372
1309
|
const _args = hasOptions ? args.slice(0, -1) : args;
|
|
1373
|
-
const inst = options?.useValue ?? (options?.useFactory ? options.useFactory(this, ..._args) : new (options?.useClass ?? cls)(this, ..._args));
|
|
1374
1310
|
const classRef = cls;
|
|
1375
|
-
const
|
|
1376
|
-
|
|
1377
|
-
for (const name of Object.getOwnPropertyNames(cls.prototype)) {
|
|
1378
|
-
if (name === "constructor") continue;
|
|
1379
|
-
const desc = Object.getOwnPropertyDescriptor(cls.prototype, name);
|
|
1380
|
-
if (desc && typeof desc.value === "function") {
|
|
1381
|
-
methodKeys.add(name);
|
|
1382
|
-
}
|
|
1383
|
-
}
|
|
1384
|
-
const entry = {
|
|
1311
|
+
const factory = (ctx) => options?.useValue ?? (options?.useFactory ? options.useFactory(ctx, ..._args) : new (options?.useClass ?? cls)(ctx, ..._args));
|
|
1312
|
+
this.provideRecords.push({
|
|
1385
1313
|
classRef,
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
pendingSets: []
|
|
1389
|
-
};
|
|
1390
|
-
this.registry.set(classRef, entry);
|
|
1391
|
-
if (provideKey) this.registry.set(provideKey, entry);
|
|
1392
|
-
this.loadSeq.push(entry);
|
|
1314
|
+
factory
|
|
1315
|
+
});
|
|
1393
1316
|
if (options?.provide) {
|
|
1394
1317
|
const prop = options.provide;
|
|
1395
1318
|
const step = (ctx) => {
|
|
@@ -1398,7 +1321,7 @@ var AppContextCore = class {
|
|
|
1398
1321
|
configurable: true,
|
|
1399
1322
|
get: () => {
|
|
1400
1323
|
const currentEntry = ctx.registry.get(classRef);
|
|
1401
|
-
return
|
|
1324
|
+
return currentEntry?.inst;
|
|
1402
1325
|
}
|
|
1403
1326
|
});
|
|
1404
1327
|
};
|
|
@@ -1417,8 +1340,6 @@ var AppContextCore = class {
|
|
|
1417
1340
|
get: () => {
|
|
1418
1341
|
const currentEntry = ctx.registry.get(classRef);
|
|
1419
1342
|
const currentInst = currentEntry?.inst;
|
|
1420
|
-
if (isPromiseLike(currentInst))
|
|
1421
|
-
return createAsyncMethod(currentInst, key);
|
|
1422
1343
|
const fn = currentInst?.[key];
|
|
1423
1344
|
return typeof fn === "function" ? fn.bind(currentInst) : fn;
|
|
1424
1345
|
}
|
|
@@ -1430,25 +1351,12 @@ var AppContextCore = class {
|
|
|
1430
1351
|
configurable: true,
|
|
1431
1352
|
get: () => {
|
|
1432
1353
|
const currentEntry = ctx.registry.get(classRef);
|
|
1433
|
-
|
|
1434
|
-
return target?.[key];
|
|
1354
|
+
return currentEntry?.inst?.[key];
|
|
1435
1355
|
},
|
|
1436
1356
|
set: (value) => {
|
|
1437
1357
|
const currentEntry = ctx.registry.get(classRef);
|
|
1438
1358
|
if (!currentEntry) return;
|
|
1439
|
-
|
|
1440
|
-
currentEntry.inst[key] = value;
|
|
1441
|
-
return;
|
|
1442
|
-
}
|
|
1443
|
-
const state = trackPromise(currentEntry.inst);
|
|
1444
|
-
if (state.status === "fulfilled") {
|
|
1445
|
-
currentEntry.inst = state.value;
|
|
1446
|
-
flushPendingSets(currentEntry);
|
|
1447
|
-
currentEntry.inst[key] = value;
|
|
1448
|
-
return;
|
|
1449
|
-
}
|
|
1450
|
-
if (state.status === "rejected") throw state.error;
|
|
1451
|
-
currentEntry.pendingSets.push({ key, value });
|
|
1359
|
+
currentEntry.inst[key] = value;
|
|
1452
1360
|
}
|
|
1453
1361
|
});
|
|
1454
1362
|
};
|
|
@@ -1467,53 +1375,24 @@ var AppContextCore = class {
|
|
|
1467
1375
|
throw new Error(`Service not provided: ${key?.name ?? cls.name}`);
|
|
1468
1376
|
}
|
|
1469
1377
|
const entry = this.registry.get(key);
|
|
1470
|
-
|
|
1471
|
-
if (isPromiseLike(inst)) {
|
|
1472
|
-
const state = trackPromise(inst);
|
|
1473
|
-
if (state.status === "fulfilled") {
|
|
1474
|
-
entry.inst = state.value;
|
|
1475
|
-
flushPendingSets(entry);
|
|
1476
|
-
return state.value;
|
|
1477
|
-
}
|
|
1478
|
-
if (state.status === "rejected") throw state.error;
|
|
1479
|
-
return wrapMaybePromise(inst, {
|
|
1480
|
-
methodKeys: entry.methodKeys
|
|
1481
|
-
});
|
|
1482
|
-
}
|
|
1483
|
-
flushPendingSets(entry);
|
|
1484
|
-
return inst;
|
|
1378
|
+
return entry.inst;
|
|
1485
1379
|
}
|
|
1380
|
+
/**
|
|
1381
|
+
* @deprecated Use get() instead. getAsync() is no longer needed as all services are loaded synchronously during start().
|
|
1382
|
+
*/
|
|
1486
1383
|
async getAsync(cls) {
|
|
1487
|
-
|
|
1488
|
-
if (!this.registry.has(key) && typeof cls === "function" && !cls.prototype) {
|
|
1489
|
-
key = cls();
|
|
1490
|
-
}
|
|
1491
|
-
if (!this.registry.has(key)) {
|
|
1492
|
-
throw new Error(`Service not provided: ${cls.name}`);
|
|
1493
|
-
}
|
|
1494
|
-
const entry = this.registry.get(key);
|
|
1495
|
-
const resolved = await resolveEntryIfNeeded(entry);
|
|
1496
|
-
return resolved;
|
|
1384
|
+
return this.get(cls);
|
|
1497
1385
|
}
|
|
1498
1386
|
use(...ctxes) {
|
|
1499
1387
|
for (const ctx of ctxes) {
|
|
1500
1388
|
const other = ctx;
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
methodKeys: new Set(item.methodKeys ?? []),
|
|
1506
|
-
pendingSets: [...item.pendingSets ?? []]
|
|
1507
|
-
}));
|
|
1508
|
-
other.loadSeq.forEach((item, index) => {
|
|
1509
|
-
entryMap.set(item, copiedSeq[index]);
|
|
1510
|
-
});
|
|
1511
|
-
this.loadSeq.push(...copiedSeq);
|
|
1389
|
+
if (this.started && !other?.started) {
|
|
1390
|
+
throw new Error(
|
|
1391
|
+
"Cannot use an unstarted context into a started context."
|
|
1392
|
+
);
|
|
1512
1393
|
}
|
|
1513
|
-
if (other?.
|
|
1514
|
-
|
|
1515
|
-
this.registry.set(key, entryMap.get(value) ?? value);
|
|
1516
|
-
}
|
|
1394
|
+
if (Array.isArray(other?.provideRecords)) {
|
|
1395
|
+
this.provideRecords.push(...other.provideRecords);
|
|
1517
1396
|
}
|
|
1518
1397
|
if (Array.isArray(other?.objectSteps)) {
|
|
1519
1398
|
this.objectSteps.push(...other.objectSteps);
|
|
@@ -1521,6 +1400,13 @@ var AppContextCore = class {
|
|
|
1521
1400
|
step(this);
|
|
1522
1401
|
}
|
|
1523
1402
|
}
|
|
1403
|
+
if (other?.started) {
|
|
1404
|
+
if (other?.registry instanceof Map) {
|
|
1405
|
+
for (const [key, value] of other.registry.entries()) {
|
|
1406
|
+
this.registry.set(key, value);
|
|
1407
|
+
}
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1524
1410
|
}
|
|
1525
1411
|
return this;
|
|
1526
1412
|
}
|
|
@@ -1528,15 +1414,35 @@ var AppContextCore = class {
|
|
|
1528
1414
|
return this;
|
|
1529
1415
|
}
|
|
1530
1416
|
async start() {
|
|
1531
|
-
|
|
1532
|
-
|
|
1417
|
+
if (this.started) {
|
|
1418
|
+
return this;
|
|
1419
|
+
}
|
|
1420
|
+
const startedEntries = [];
|
|
1421
|
+
const preloadedKeys = new Set(this.registry.keys());
|
|
1422
|
+
for (const record of this.provideRecords) {
|
|
1423
|
+
if (preloadedKeys.has(record.classRef)) {
|
|
1424
|
+
continue;
|
|
1425
|
+
}
|
|
1426
|
+
const inst = record.factory(this);
|
|
1427
|
+
const entry = {
|
|
1428
|
+
classRef: record.classRef,
|
|
1429
|
+
inst
|
|
1430
|
+
};
|
|
1431
|
+
this.registry.set(record.classRef, entry);
|
|
1432
|
+
startedEntries.push(entry);
|
|
1433
|
+
}
|
|
1434
|
+
for (const entry of startedEntries) {
|
|
1435
|
+
if (entry.inst && typeof entry.inst.then === "function") {
|
|
1436
|
+
entry.inst = await entry.inst;
|
|
1437
|
+
}
|
|
1533
1438
|
}
|
|
1534
|
-
for (const entry of
|
|
1439
|
+
for (const entry of startedEntries) {
|
|
1535
1440
|
const inst = entry.inst;
|
|
1536
1441
|
if (inst && typeof inst.init === "function") {
|
|
1537
1442
|
await inst.init();
|
|
1538
1443
|
}
|
|
1539
1444
|
}
|
|
1445
|
+
this.started = true;
|
|
1540
1446
|
return this;
|
|
1541
1447
|
}
|
|
1542
1448
|
};
|