nfkit 1.0.25 → 1.0.26
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 +48 -142
- package/dist/index.cjs.map +4 -4
- package/dist/index.mjs +48 -142
- package/dist/index.mjs.map +4 -4
- package/dist/src/app-context/app-context.d.ts +9 -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,54 +1285,6 @@ 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
1289
|
var ProvidePrefix = "provide:";
|
|
1338
1290
|
var getMethodDescriptor = (cls, key) => {
|
|
@@ -1344,52 +1296,27 @@ var getMethodDescriptor = (cls, key) => {
|
|
|
1344
1296
|
}
|
|
1345
1297
|
return void 0;
|
|
1346
1298
|
};
|
|
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
1299
|
var AppContextCore = class {
|
|
1363
1300
|
constructor() {
|
|
1301
|
+
this.provideRecords = [];
|
|
1364
1302
|
this.registry = /* @__PURE__ */ new Map();
|
|
1365
1303
|
this.loadSeq = [];
|
|
1366
1304
|
this.objectSteps = [];
|
|
1305
|
+
this.started = false;
|
|
1367
1306
|
}
|
|
1368
1307
|
provide(cls, ...args) {
|
|
1369
1308
|
const last = args[args.length - 1];
|
|
1370
1309
|
const hasOptions = !!last && typeof last === "object" && ("provide" in last || "merge" in last || "useValue" in last || "useFactory" in last || "useClass" in last);
|
|
1371
1310
|
const options = hasOptions ? last : void 0;
|
|
1372
1311
|
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
1312
|
const classRef = cls;
|
|
1375
1313
|
const provideKey = options?.provide ? ProvidePrefix + String(options.provide) : void 0;
|
|
1376
|
-
const
|
|
1377
|
-
|
|
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 = {
|
|
1314
|
+
const factory = () => options?.useValue ?? (options?.useFactory ? options.useFactory(this, ..._args) : new (options?.useClass ?? cls)(this, ..._args));
|
|
1315
|
+
this.provideRecords.push({
|
|
1385
1316
|
classRef,
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
};
|
|
1390
|
-
this.registry.set(classRef, entry);
|
|
1391
|
-
if (provideKey) this.registry.set(provideKey, entry);
|
|
1392
|
-
this.loadSeq.push(entry);
|
|
1317
|
+
factory,
|
|
1318
|
+
provideKey
|
|
1319
|
+
});
|
|
1393
1320
|
if (options?.provide) {
|
|
1394
1321
|
const prop = options.provide;
|
|
1395
1322
|
const step = (ctx) => {
|
|
@@ -1398,7 +1325,7 @@ var AppContextCore = class {
|
|
|
1398
1325
|
configurable: true,
|
|
1399
1326
|
get: () => {
|
|
1400
1327
|
const currentEntry = ctx.registry.get(classRef);
|
|
1401
|
-
return
|
|
1328
|
+
return currentEntry?.inst;
|
|
1402
1329
|
}
|
|
1403
1330
|
});
|
|
1404
1331
|
};
|
|
@@ -1417,8 +1344,6 @@ var AppContextCore = class {
|
|
|
1417
1344
|
get: () => {
|
|
1418
1345
|
const currentEntry = ctx.registry.get(classRef);
|
|
1419
1346
|
const currentInst = currentEntry?.inst;
|
|
1420
|
-
if (isPromiseLike(currentInst))
|
|
1421
|
-
return createAsyncMethod(currentInst, key);
|
|
1422
1347
|
const fn = currentInst?.[key];
|
|
1423
1348
|
return typeof fn === "function" ? fn.bind(currentInst) : fn;
|
|
1424
1349
|
}
|
|
@@ -1430,25 +1355,12 @@ var AppContextCore = class {
|
|
|
1430
1355
|
configurable: true,
|
|
1431
1356
|
get: () => {
|
|
1432
1357
|
const currentEntry = ctx.registry.get(classRef);
|
|
1433
|
-
|
|
1434
|
-
return target?.[key];
|
|
1358
|
+
return currentEntry?.inst?.[key];
|
|
1435
1359
|
},
|
|
1436
1360
|
set: (value) => {
|
|
1437
1361
|
const currentEntry = ctx.registry.get(classRef);
|
|
1438
1362
|
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 });
|
|
1363
|
+
currentEntry.inst[key] = value;
|
|
1452
1364
|
}
|
|
1453
1365
|
});
|
|
1454
1366
|
};
|
|
@@ -1467,53 +1379,19 @@ var AppContextCore = class {
|
|
|
1467
1379
|
throw new Error(`Service not provided: ${key?.name ?? cls.name}`);
|
|
1468
1380
|
}
|
|
1469
1381
|
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;
|
|
1382
|
+
return entry.inst;
|
|
1485
1383
|
}
|
|
1384
|
+
/**
|
|
1385
|
+
* @deprecated Use get() instead. getAsync() is no longer needed as all services are loaded synchronously during start().
|
|
1386
|
+
*/
|
|
1486
1387
|
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;
|
|
1388
|
+
return this.get(cls);
|
|
1497
1389
|
}
|
|
1498
1390
|
use(...ctxes) {
|
|
1499
1391
|
for (const ctx of ctxes) {
|
|
1500
1392
|
const other = ctx;
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
const copiedSeq = other.loadSeq.map((item) => ({
|
|
1504
|
-
...item,
|
|
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);
|
|
1512
|
-
}
|
|
1513
|
-
if (other?.registry instanceof Map) {
|
|
1514
|
-
for (const [key, value] of other.registry.entries()) {
|
|
1515
|
-
this.registry.set(key, entryMap.get(value) ?? value);
|
|
1516
|
-
}
|
|
1393
|
+
if (Array.isArray(other?.provideRecords)) {
|
|
1394
|
+
this.provideRecords.push(...other.provideRecords);
|
|
1517
1395
|
}
|
|
1518
1396
|
if (Array.isArray(other?.objectSteps)) {
|
|
1519
1397
|
this.objectSteps.push(...other.objectSteps);
|
|
@@ -1521,6 +1399,16 @@ var AppContextCore = class {
|
|
|
1521
1399
|
step(this);
|
|
1522
1400
|
}
|
|
1523
1401
|
}
|
|
1402
|
+
if (other?.started) {
|
|
1403
|
+
if (Array.isArray(other?.loadSeq)) {
|
|
1404
|
+
this.loadSeq.push(...other.loadSeq);
|
|
1405
|
+
}
|
|
1406
|
+
if (other?.registry instanceof Map) {
|
|
1407
|
+
for (const [key, value] of other.registry.entries()) {
|
|
1408
|
+
this.registry.set(key, value);
|
|
1409
|
+
}
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1524
1412
|
}
|
|
1525
1413
|
return this;
|
|
1526
1414
|
}
|
|
@@ -1528,8 +1416,25 @@ var AppContextCore = class {
|
|
|
1528
1416
|
return this;
|
|
1529
1417
|
}
|
|
1530
1418
|
async start() {
|
|
1419
|
+
if (this.started) {
|
|
1420
|
+
return this;
|
|
1421
|
+
}
|
|
1422
|
+
for (const record of this.provideRecords) {
|
|
1423
|
+
const inst = record.factory();
|
|
1424
|
+
const entry = {
|
|
1425
|
+
classRef: record.classRef,
|
|
1426
|
+
inst
|
|
1427
|
+
};
|
|
1428
|
+
this.registry.set(record.classRef, entry);
|
|
1429
|
+
if (record.provideKey) {
|
|
1430
|
+
this.registry.set(record.provideKey, entry);
|
|
1431
|
+
}
|
|
1432
|
+
this.loadSeq.push(entry);
|
|
1433
|
+
}
|
|
1531
1434
|
for (const entry of this.loadSeq) {
|
|
1532
|
-
|
|
1435
|
+
if (entry.inst && typeof entry.inst.then === "function") {
|
|
1436
|
+
entry.inst = await entry.inst;
|
|
1437
|
+
}
|
|
1533
1438
|
}
|
|
1534
1439
|
for (const entry of this.loadSeq) {
|
|
1535
1440
|
const inst = entry.inst;
|
|
@@ -1537,6 +1442,7 @@ var AppContextCore = class {
|
|
|
1537
1442
|
await inst.init();
|
|
1538
1443
|
}
|
|
1539
1444
|
}
|
|
1445
|
+
this.started = true;
|
|
1540
1446
|
return this;
|
|
1541
1447
|
}
|
|
1542
1448
|
};
|