@kehto/shell 0.21.1 → 0.21.3
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 +28 -3
- package/dist/index.js +72 -1
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -85,9 +85,10 @@ unsupported fields and caller-supplied sender data, and resolves only
|
|
|
85
85
|
parent-originated correlated results.
|
|
86
86
|
|
|
87
87
|
Successful results include `handled`, `handler`, `windowId`, and `convention`
|
|
88
|
-
after target dispatch completes.
|
|
89
|
-
|
|
90
|
-
|
|
88
|
+
after target dispatch completes. Target delivery now follows NAP-INTENT at
|
|
89
|
+
`25b29ee49e5bff8ebfe031f4b76dce98705c8b7e`: one `intent.deliver` envelope
|
|
90
|
+
feeds the buffered `onDelivery` binding described below. Broader invocation and
|
|
91
|
+
result changes from that newer spec remain deferred.
|
|
91
92
|
|
|
92
93
|
Phase 105 completed released `@napplet/*` package adoption and persistent live
|
|
93
94
|
Paja/playground catalogs and target controllers. The Phase 104 Paja simulator
|
|
@@ -211,3 +212,27 @@ Generated API module: `docs/api/modules/_kehto_shell.html` (run `pnpm docs:api`)
|
|
|
211
212
|
## License
|
|
212
213
|
|
|
213
214
|
MIT
|
|
215
|
+
|
|
216
|
+
## NIP-5D event compatibility
|
|
217
|
+
|
|
218
|
+
Current manifests use a direct artifact `x` hash, plain-text `content`, independent
|
|
219
|
+
`z`/`i` routing declarations, and required `R` / optional `O` domains. Kehto also
|
|
220
|
+
accepts legacy aggregate events through an isolated compatibility adapter.
|
|
221
|
+
Existing `aggregateHash` host/cache/ACL fields carry the verified artifact hash
|
|
222
|
+
for current events; legacy identities keep their original aggregate. Both paths
|
|
223
|
+
verify signatures and bytes before runtime injection and `srcdoc` execution.
|
|
224
|
+
For the schema and removal boundary, see [event migration](https://kehto.github.io/web/docs/migrations/NIP-5D-EVENT-SCHEMA.html).
|
|
225
|
+
|
|
226
|
+
### Intent delivery
|
|
227
|
+
|
|
228
|
+
The injected `window.napplet.intent.onDelivery(handler)` returns a closeable
|
|
229
|
+
subscription and drains buffered parent deliveries in order. Register it to
|
|
230
|
+
receive `{ sender, archetype, action, convention, payload? }`; INC is not required.
|
|
231
|
+
Its receiver is installed before `shell.ready` and survives namespace reassignment.
|
|
232
|
+
A throwing listener does not prevent delivery to other listeners.
|
|
233
|
+
|
|
234
|
+
When no canonical listener is registered, matching legacy INC listeners can
|
|
235
|
+
consume the delivery locally. This emits `KEHTO_COMPAT_INTENT_INC` once per
|
|
236
|
+
iframe; a delivery is never replayed to both APIs. See [compatibility tracking](https://github.com/kehto/web/blob/main/docs/compatibility.md).
|
|
237
|
+
This aligns delivery with NAP-INTENT at `25b29ee`; broader invocation/result
|
|
238
|
+
changes and the packaged SDK upgrade remain deferred.
|
package/dist/index.js
CHANGED
|
@@ -389,7 +389,7 @@ var originRegistry = {
|
|
|
389
389
|
*/
|
|
390
390
|
getIdentity(win) {
|
|
391
391
|
const entry = registry.get(win);
|
|
392
|
-
if (
|
|
392
|
+
if (typeof entry?.dTag !== "string" || !entry?.aggregateHash) return void 0;
|
|
393
393
|
return { dTag: entry.dTag, aggregateHash: entry.aggregateHash };
|
|
394
394
|
},
|
|
395
395
|
/** Store the immutable environment captured for this exact frame registration. */
|
|
@@ -1691,7 +1691,13 @@ function nappletNamespacePrelude(domains) {
|
|
|
1691
1691
|
fire({ type: "inc.subscribe", id: subscriptionId, topic: stableTopic });
|
|
1692
1692
|
}
|
|
1693
1693
|
state.handlers.add(callback);
|
|
1694
|
+
const offLegacy = intentDelivery?.onLegacy(stableTopic, (delivery) => callback({
|
|
1695
|
+
topic: delivery.convention,
|
|
1696
|
+
sender: delivery.sender,
|
|
1697
|
+
...Object.prototype.hasOwnProperty.call(delivery, "payload") ? { payload: delivery.payload } : {}
|
|
1698
|
+
}));
|
|
1694
1699
|
return subscriptionHandle(() => {
|
|
1700
|
+
offLegacy?.();
|
|
1695
1701
|
const current = topicStates.get(stableTopic);
|
|
1696
1702
|
if (!current) return;
|
|
1697
1703
|
current.handlers.delete(callback);
|
|
@@ -2253,6 +2259,69 @@ function nappletNamespacePrelude(domains) {
|
|
|
2253
2259
|
}
|
|
2254
2260
|
};
|
|
2255
2261
|
}
|
|
2262
|
+
function makeIntentDelivery() {
|
|
2263
|
+
const handlers = /* @__PURE__ */ new Set();
|
|
2264
|
+
const legacy = /* @__PURE__ */ new Map();
|
|
2265
|
+
const pending = [];
|
|
2266
|
+
let draining = false;
|
|
2267
|
+
let warned = false;
|
|
2268
|
+
function drain() {
|
|
2269
|
+
if (draining) return;
|
|
2270
|
+
draining = true;
|
|
2271
|
+
try {
|
|
2272
|
+
while (pending.length > 0) {
|
|
2273
|
+
const index = handlers.size > 0 ? 0 : pending.findIndex((delivery2) => [...legacy.values()].includes(delivery2.convention));
|
|
2274
|
+
if (index < 0) break;
|
|
2275
|
+
const [delivery] = pending.splice(index, 1);
|
|
2276
|
+
const canonical = handlers.size > 0;
|
|
2277
|
+
const recipients = canonical ? [...handlers] : [...legacy.entries()].filter(([, topic]) => topic === delivery.convention).map(([handler]) => handler);
|
|
2278
|
+
if (!canonical && !warned) {
|
|
2279
|
+
warned = true;
|
|
2280
|
+
console.warn("[KEHTO_COMPAT_INTENT_INC] Intent delivered to a legacy INC listener. Migrate to window.napplet.intent.onDelivery. See docs/compatibility.md.");
|
|
2281
|
+
}
|
|
2282
|
+
for (const handler of recipients) {
|
|
2283
|
+
try {
|
|
2284
|
+
handler(delivery);
|
|
2285
|
+
} catch (error) {
|
|
2286
|
+
console.error("Intent delivery handler failed", error);
|
|
2287
|
+
}
|
|
2288
|
+
}
|
|
2289
|
+
}
|
|
2290
|
+
} finally {
|
|
2291
|
+
draining = false;
|
|
2292
|
+
}
|
|
2293
|
+
}
|
|
2294
|
+
listen((event) => {
|
|
2295
|
+
if (!isParentMessage(event)) return;
|
|
2296
|
+
const message = event.data;
|
|
2297
|
+
if (!message || message.type !== "intent.deliver") return;
|
|
2298
|
+
const value = message.delivery;
|
|
2299
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return;
|
|
2300
|
+
const delivery = value;
|
|
2301
|
+
if (typeof delivery.sender !== "string" || typeof delivery.archetype !== "string" || typeof delivery.action !== "string" || typeof delivery.convention !== "string") return;
|
|
2302
|
+
pending.push(Object.freeze({
|
|
2303
|
+
sender: delivery.sender,
|
|
2304
|
+
archetype: delivery.archetype,
|
|
2305
|
+
action: delivery.action,
|
|
2306
|
+
convention: delivery.convention,
|
|
2307
|
+
...Object.prototype.hasOwnProperty.call(delivery, "payload") ? { payload: delivery.payload } : {}
|
|
2308
|
+
}));
|
|
2309
|
+
drain();
|
|
2310
|
+
});
|
|
2311
|
+
return {
|
|
2312
|
+
onDelivery(handler) {
|
|
2313
|
+
if (typeof handler !== "function") throw new TypeError("Intent delivery handler must be a function");
|
|
2314
|
+
handlers.add(handler);
|
|
2315
|
+
drain();
|
|
2316
|
+
return subscriptionHandle(() => handlers.delete(handler));
|
|
2317
|
+
},
|
|
2318
|
+
onLegacy(topic, handler) {
|
|
2319
|
+
legacy.set(handler, topic);
|
|
2320
|
+
drain();
|
|
2321
|
+
return () => legacy.delete(handler);
|
|
2322
|
+
}
|
|
2323
|
+
};
|
|
2324
|
+
}
|
|
2256
2325
|
function makeIntent() {
|
|
2257
2326
|
const hasOwn = (value, key) => Object.prototype.hasOwnProperty.call(value, key);
|
|
2258
2327
|
const normalizeRequest = (value) => {
|
|
@@ -2311,6 +2380,7 @@ function nappletNamespacePrelude(domains) {
|
|
|
2311
2380
|
);
|
|
2312
2381
|
};
|
|
2313
2382
|
return {
|
|
2383
|
+
onDelivery: intentDelivery.onDelivery,
|
|
2314
2384
|
invoke,
|
|
2315
2385
|
open: (archetype, payload, opts) => invoke({
|
|
2316
2386
|
archetype,
|
|
@@ -2490,6 +2560,7 @@ function nappletNamespacePrelude(domains) {
|
|
|
2490
2560
|
onChanged: (callback) => domainEventHandle("fs.changed", callback, (msg) => msg.change)
|
|
2491
2561
|
};
|
|
2492
2562
|
}
|
|
2563
|
+
const intentDelivery = allowed.has("intent") ? makeIntentDelivery() : void 0;
|
|
2493
2564
|
const shell = makeShell();
|
|
2494
2565
|
let inc;
|
|
2495
2566
|
let identity;
|