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.mjs
CHANGED
|
@@ -1201,11 +1201,11 @@ var observeDiff = (obj, cb) => {
|
|
|
1201
1201
|
// src/memorize.ts
|
|
1202
1202
|
var Memorize = () => {
|
|
1203
1203
|
const cache = /* @__PURE__ */ new WeakMap();
|
|
1204
|
-
const
|
|
1204
|
+
const isPromiseLike = (v) => v != null && typeof v.then === "function" && typeof v.catch === "function";
|
|
1205
1205
|
const getOrSet = (instance, compute) => {
|
|
1206
1206
|
if (cache.has(instance)) return cache.get(instance);
|
|
1207
1207
|
const result = compute();
|
|
1208
|
-
if (
|
|
1208
|
+
if (isPromiseLike(result)) {
|
|
1209
1209
|
const wrapped = result.catch((err) => {
|
|
1210
1210
|
cache.delete(instance);
|
|
1211
1211
|
throw err;
|
|
@@ -1239,56 +1239,7 @@ var makeArray = (value) => {
|
|
|
1239
1239
|
return Array.isArray(value) ? value : [value];
|
|
1240
1240
|
};
|
|
1241
1241
|
|
|
1242
|
-
// src/app-context/promise-utils.ts
|
|
1243
|
-
var promiseStates = /* @__PURE__ */ new WeakMap();
|
|
1244
|
-
var isPromiseLike = (value) => !!value && typeof value.then === "function";
|
|
1245
|
-
var trackPromise = (promise) => {
|
|
1246
|
-
const existing = promiseStates.get(promise);
|
|
1247
|
-
if (existing) return existing;
|
|
1248
|
-
const state = { status: "pending" };
|
|
1249
|
-
promiseStates.set(promise, state);
|
|
1250
|
-
promise.then(
|
|
1251
|
-
(value) => {
|
|
1252
|
-
state.status = "fulfilled";
|
|
1253
|
-
state.value = value;
|
|
1254
|
-
},
|
|
1255
|
-
(error) => {
|
|
1256
|
-
state.status = "rejected";
|
|
1257
|
-
state.error = error;
|
|
1258
|
-
}
|
|
1259
|
-
);
|
|
1260
|
-
return state;
|
|
1261
|
-
};
|
|
1262
|
-
var wrapMaybePromise = (value, options) => {
|
|
1263
|
-
if (!isPromiseLike(value)) return value;
|
|
1264
|
-
const promise = Promise.resolve(value);
|
|
1265
|
-
const state = trackPromise(promise);
|
|
1266
|
-
if (state.status === "fulfilled") return state.value;
|
|
1267
|
-
if (state.status === "rejected") throw state.error;
|
|
1268
|
-
return dualizeAny(
|
|
1269
|
-
() => {
|
|
1270
|
-
const current = trackPromise(promise);
|
|
1271
|
-
if (current.status === "fulfilled") return current.value;
|
|
1272
|
-
if (current.status === "rejected") throw current.error;
|
|
1273
|
-
throwDualPending();
|
|
1274
|
-
},
|
|
1275
|
-
() => promise,
|
|
1276
|
-
{
|
|
1277
|
-
// Intentionally hide strict method return type here.
|
|
1278
|
-
asyncMethods: Array.from(options?.methodKeys ?? [])
|
|
1279
|
-
}
|
|
1280
|
-
);
|
|
1281
|
-
};
|
|
1282
|
-
var createAsyncMethod = (inst, key) => (...args) => Promise.resolve(inst).then((resolved) => {
|
|
1283
|
-
const fn = resolved?.[key];
|
|
1284
|
-
if (typeof fn !== "function") {
|
|
1285
|
-
throw new TypeError("Target method is not a function");
|
|
1286
|
-
}
|
|
1287
|
-
return fn.apply(resolved, args);
|
|
1288
|
-
});
|
|
1289
|
-
|
|
1290
1242
|
// src/app-context/app-context.ts
|
|
1291
|
-
var ProvidePrefix = "provide:";
|
|
1292
1243
|
var getMethodDescriptor = (cls, key) => {
|
|
1293
1244
|
let proto = cls.prototype;
|
|
1294
1245
|
while (proto && proto !== Object.prototype) {
|
|
@@ -1298,52 +1249,24 @@ var getMethodDescriptor = (cls, key) => {
|
|
|
1298
1249
|
}
|
|
1299
1250
|
return void 0;
|
|
1300
1251
|
};
|
|
1301
|
-
var flushPendingSets = (entry) => {
|
|
1302
|
-
if (isPromiseLike(entry.inst)) return;
|
|
1303
|
-
if (!entry.pendingSets.length) return;
|
|
1304
|
-
for (const item of entry.pendingSets) {
|
|
1305
|
-
entry.inst[item.key] = item.value;
|
|
1306
|
-
}
|
|
1307
|
-
entry.pendingSets.length = 0;
|
|
1308
|
-
};
|
|
1309
|
-
var resolveEntryIfNeeded = async (entry) => {
|
|
1310
|
-
if (isPromiseLike(entry.inst)) {
|
|
1311
|
-
entry.inst = await entry.inst;
|
|
1312
|
-
}
|
|
1313
|
-
flushPendingSets(entry);
|
|
1314
|
-
return entry.inst;
|
|
1315
|
-
};
|
|
1316
1252
|
var AppContextCore = class {
|
|
1317
1253
|
constructor() {
|
|
1254
|
+
this.provideRecords = [];
|
|
1318
1255
|
this.registry = /* @__PURE__ */ new Map();
|
|
1319
|
-
this.loadSeq = [];
|
|
1320
1256
|
this.objectSteps = [];
|
|
1257
|
+
this.started = false;
|
|
1321
1258
|
}
|
|
1322
1259
|
provide(cls, ...args) {
|
|
1323
1260
|
const last = args[args.length - 1];
|
|
1324
1261
|
const hasOptions = !!last && typeof last === "object" && ("provide" in last || "merge" in last || "useValue" in last || "useFactory" in last || "useClass" in last);
|
|
1325
1262
|
const options = hasOptions ? last : void 0;
|
|
1326
1263
|
const _args = hasOptions ? args.slice(0, -1) : args;
|
|
1327
|
-
const inst = options?.useValue ?? (options?.useFactory ? options.useFactory(this, ..._args) : new (options?.useClass ?? cls)(this, ..._args));
|
|
1328
1264
|
const classRef = cls;
|
|
1329
|
-
const
|
|
1330
|
-
|
|
1331
|
-
for (const name of Object.getOwnPropertyNames(cls.prototype)) {
|
|
1332
|
-
if (name === "constructor") continue;
|
|
1333
|
-
const desc = Object.getOwnPropertyDescriptor(cls.prototype, name);
|
|
1334
|
-
if (desc && typeof desc.value === "function") {
|
|
1335
|
-
methodKeys.add(name);
|
|
1336
|
-
}
|
|
1337
|
-
}
|
|
1338
|
-
const entry = {
|
|
1265
|
+
const factory = (ctx) => options?.useValue ?? (options?.useFactory ? options.useFactory(ctx, ..._args) : new (options?.useClass ?? cls)(ctx, ..._args));
|
|
1266
|
+
this.provideRecords.push({
|
|
1339
1267
|
classRef,
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
pendingSets: []
|
|
1343
|
-
};
|
|
1344
|
-
this.registry.set(classRef, entry);
|
|
1345
|
-
if (provideKey) this.registry.set(provideKey, entry);
|
|
1346
|
-
this.loadSeq.push(entry);
|
|
1268
|
+
factory
|
|
1269
|
+
});
|
|
1347
1270
|
if (options?.provide) {
|
|
1348
1271
|
const prop = options.provide;
|
|
1349
1272
|
const step = (ctx) => {
|
|
@@ -1352,7 +1275,7 @@ var AppContextCore = class {
|
|
|
1352
1275
|
configurable: true,
|
|
1353
1276
|
get: () => {
|
|
1354
1277
|
const currentEntry = ctx.registry.get(classRef);
|
|
1355
|
-
return
|
|
1278
|
+
return currentEntry?.inst;
|
|
1356
1279
|
}
|
|
1357
1280
|
});
|
|
1358
1281
|
};
|
|
@@ -1371,8 +1294,6 @@ var AppContextCore = class {
|
|
|
1371
1294
|
get: () => {
|
|
1372
1295
|
const currentEntry = ctx.registry.get(classRef);
|
|
1373
1296
|
const currentInst = currentEntry?.inst;
|
|
1374
|
-
if (isPromiseLike(currentInst))
|
|
1375
|
-
return createAsyncMethod(currentInst, key);
|
|
1376
1297
|
const fn = currentInst?.[key];
|
|
1377
1298
|
return typeof fn === "function" ? fn.bind(currentInst) : fn;
|
|
1378
1299
|
}
|
|
@@ -1384,25 +1305,12 @@ var AppContextCore = class {
|
|
|
1384
1305
|
configurable: true,
|
|
1385
1306
|
get: () => {
|
|
1386
1307
|
const currentEntry = ctx.registry.get(classRef);
|
|
1387
|
-
|
|
1388
|
-
return target?.[key];
|
|
1308
|
+
return currentEntry?.inst?.[key];
|
|
1389
1309
|
},
|
|
1390
1310
|
set: (value) => {
|
|
1391
1311
|
const currentEntry = ctx.registry.get(classRef);
|
|
1392
1312
|
if (!currentEntry) return;
|
|
1393
|
-
|
|
1394
|
-
currentEntry.inst[key] = value;
|
|
1395
|
-
return;
|
|
1396
|
-
}
|
|
1397
|
-
const state = trackPromise(currentEntry.inst);
|
|
1398
|
-
if (state.status === "fulfilled") {
|
|
1399
|
-
currentEntry.inst = state.value;
|
|
1400
|
-
flushPendingSets(currentEntry);
|
|
1401
|
-
currentEntry.inst[key] = value;
|
|
1402
|
-
return;
|
|
1403
|
-
}
|
|
1404
|
-
if (state.status === "rejected") throw state.error;
|
|
1405
|
-
currentEntry.pendingSets.push({ key, value });
|
|
1313
|
+
currentEntry.inst[key] = value;
|
|
1406
1314
|
}
|
|
1407
1315
|
});
|
|
1408
1316
|
};
|
|
@@ -1421,53 +1329,24 @@ var AppContextCore = class {
|
|
|
1421
1329
|
throw new Error(`Service not provided: ${key?.name ?? cls.name}`);
|
|
1422
1330
|
}
|
|
1423
1331
|
const entry = this.registry.get(key);
|
|
1424
|
-
|
|
1425
|
-
if (isPromiseLike(inst)) {
|
|
1426
|
-
const state = trackPromise(inst);
|
|
1427
|
-
if (state.status === "fulfilled") {
|
|
1428
|
-
entry.inst = state.value;
|
|
1429
|
-
flushPendingSets(entry);
|
|
1430
|
-
return state.value;
|
|
1431
|
-
}
|
|
1432
|
-
if (state.status === "rejected") throw state.error;
|
|
1433
|
-
return wrapMaybePromise(inst, {
|
|
1434
|
-
methodKeys: entry.methodKeys
|
|
1435
|
-
});
|
|
1436
|
-
}
|
|
1437
|
-
flushPendingSets(entry);
|
|
1438
|
-
return inst;
|
|
1332
|
+
return entry.inst;
|
|
1439
1333
|
}
|
|
1334
|
+
/**
|
|
1335
|
+
* @deprecated Use get() instead. getAsync() is no longer needed as all services are loaded synchronously during start().
|
|
1336
|
+
*/
|
|
1440
1337
|
async getAsync(cls) {
|
|
1441
|
-
|
|
1442
|
-
if (!this.registry.has(key) && typeof cls === "function" && !cls.prototype) {
|
|
1443
|
-
key = cls();
|
|
1444
|
-
}
|
|
1445
|
-
if (!this.registry.has(key)) {
|
|
1446
|
-
throw new Error(`Service not provided: ${cls.name}`);
|
|
1447
|
-
}
|
|
1448
|
-
const entry = this.registry.get(key);
|
|
1449
|
-
const resolved = await resolveEntryIfNeeded(entry);
|
|
1450
|
-
return resolved;
|
|
1338
|
+
return this.get(cls);
|
|
1451
1339
|
}
|
|
1452
1340
|
use(...ctxes) {
|
|
1453
1341
|
for (const ctx of ctxes) {
|
|
1454
1342
|
const other = ctx;
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
methodKeys: new Set(item.methodKeys ?? []),
|
|
1460
|
-
pendingSets: [...item.pendingSets ?? []]
|
|
1461
|
-
}));
|
|
1462
|
-
other.loadSeq.forEach((item, index) => {
|
|
1463
|
-
entryMap.set(item, copiedSeq[index]);
|
|
1464
|
-
});
|
|
1465
|
-
this.loadSeq.push(...copiedSeq);
|
|
1343
|
+
if (this.started && !other?.started) {
|
|
1344
|
+
throw new Error(
|
|
1345
|
+
"Cannot use an unstarted context into a started context."
|
|
1346
|
+
);
|
|
1466
1347
|
}
|
|
1467
|
-
if (other?.
|
|
1468
|
-
|
|
1469
|
-
this.registry.set(key, entryMap.get(value) ?? value);
|
|
1470
|
-
}
|
|
1348
|
+
if (Array.isArray(other?.provideRecords)) {
|
|
1349
|
+
this.provideRecords.push(...other.provideRecords);
|
|
1471
1350
|
}
|
|
1472
1351
|
if (Array.isArray(other?.objectSteps)) {
|
|
1473
1352
|
this.objectSteps.push(...other.objectSteps);
|
|
@@ -1475,6 +1354,13 @@ var AppContextCore = class {
|
|
|
1475
1354
|
step(this);
|
|
1476
1355
|
}
|
|
1477
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
|
+
}
|
|
1478
1364
|
}
|
|
1479
1365
|
return this;
|
|
1480
1366
|
}
|
|
@@ -1482,15 +1368,35 @@ var AppContextCore = class {
|
|
|
1482
1368
|
return this;
|
|
1483
1369
|
}
|
|
1484
1370
|
async start() {
|
|
1485
|
-
|
|
1486
|
-
|
|
1371
|
+
if (this.started) {
|
|
1372
|
+
return this;
|
|
1373
|
+
}
|
|
1374
|
+
const startedEntries = [];
|
|
1375
|
+
const preloadedKeys = new Set(this.registry.keys());
|
|
1376
|
+
for (const record of this.provideRecords) {
|
|
1377
|
+
if (preloadedKeys.has(record.classRef)) {
|
|
1378
|
+
continue;
|
|
1379
|
+
}
|
|
1380
|
+
const inst = record.factory(this);
|
|
1381
|
+
const entry = {
|
|
1382
|
+
classRef: record.classRef,
|
|
1383
|
+
inst
|
|
1384
|
+
};
|
|
1385
|
+
this.registry.set(record.classRef, entry);
|
|
1386
|
+
startedEntries.push(entry);
|
|
1387
|
+
}
|
|
1388
|
+
for (const entry of startedEntries) {
|
|
1389
|
+
if (entry.inst && typeof entry.inst.then === "function") {
|
|
1390
|
+
entry.inst = await entry.inst;
|
|
1391
|
+
}
|
|
1487
1392
|
}
|
|
1488
|
-
for (const entry of
|
|
1393
|
+
for (const entry of startedEntries) {
|
|
1489
1394
|
const inst = entry.inst;
|
|
1490
1395
|
if (inst && typeof inst.init === "function") {
|
|
1491
1396
|
await inst.init();
|
|
1492
1397
|
}
|
|
1493
1398
|
}
|
|
1399
|
+
this.started = true;
|
|
1494
1400
|
return this;
|
|
1495
1401
|
}
|
|
1496
1402
|
};
|