@immediately-run/sdk 0.51.0 → 0.52.0
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/analytics.cjs +47 -0
- package/dist/analytics.cjs.map +1 -0
- package/dist/analytics.d.cts +46 -0
- package/dist/analytics.d.ts +46 -0
- package/dist/analytics.js +21 -0
- package/dist/analytics.js.map +1 -0
- package/dist/corpus.cjs +91 -0
- package/dist/corpus.cjs.map +1 -0
- package/dist/corpus.d.cts +63 -0
- package/dist/corpus.d.ts +63 -0
- package/dist/corpus.js +62 -0
- package/dist/corpus.js.map +1 -0
- package/dist/index.cjs +4 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/protocolSchemes.cjs +1 -0
- package/dist/protocolSchemes.cjs.map +1 -1
- package/dist/protocolSchemes.d.cts +1 -0
- package/dist/protocolSchemes.d.ts +1 -0
- package/dist/protocolSchemes.js +2 -0
- package/dist/protocolSchemes.js.map +1 -1
- package/dist/version.cjs +1 -1
- package/dist/version.cjs.map +1 -1
- package/dist/version.d.cts +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var analytics_exports = {};
|
|
20
|
+
__export(analytics_exports, {
|
|
21
|
+
emitAnalyticsEvent: () => emitAnalyticsEvent,
|
|
22
|
+
recordRoute: () => recordRoute,
|
|
23
|
+
track: () => track,
|
|
24
|
+
trackRoute: () => trackRoute
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(analytics_exports);
|
|
27
|
+
var import_sandboxUtils = require("./sandboxUtils");
|
|
28
|
+
var import_protocolSchemes = require("./protocolSchemes");
|
|
29
|
+
var import_protocol = require("./generated/protocol");
|
|
30
|
+
const emitAnalyticsEvent = (name, props) => (0, import_sandboxUtils.protocolRequest)(import_protocolSchemes.SCHEMES[import_protocol.PROTOCOL_ANALYTICS], "emit", [{ name, ...props ? { props } : {} }]);
|
|
31
|
+
const recordRoute = (path) => (0, import_sandboxUtils.protocolRequest)(import_protocolSchemes.SCHEMES[import_protocol.PROTOCOL_ANALYTICS], "route", [{ path }]);
|
|
32
|
+
const track = (name, props) => {
|
|
33
|
+
void emitAnalyticsEvent(name, props).catch(() => {
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
const trackRoute = (path) => {
|
|
37
|
+
void recordRoute(path).catch(() => {
|
|
38
|
+
});
|
|
39
|
+
};
|
|
40
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
41
|
+
0 && (module.exports = {
|
|
42
|
+
emitAnalyticsEvent,
|
|
43
|
+
recordRoute,
|
|
44
|
+
track,
|
|
45
|
+
trackRoute
|
|
46
|
+
});
|
|
47
|
+
//# sourceMappingURL=analytics.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/analytics.ts"],"sourcesContent":["// App analytics — the app-facing surface for `analytics:emit`\n// (APP_ANALYTICS_SPEC §2/§3/§5, roadmap R3-350).\n//\n// ─────────────────────────────────────────────────────────────────────────────\n// WHAT THIS IS FOR, STATED HONESTLY\n// ─────────────────────────────────────────────────────────────────────────────\n//\n// An app runs in an opaque-origin sandboxed iframe where even touching\n// `localStorage` throws. It has no storage and no identity of its own, so **a\n// publisher has no way to learn how their app is used.**\n//\n// The honest argument for this capability is *not* that it displaces `net:fetch` —\n// it does not displace anything, and nothing here narrows or discourages\n// `net:fetch`. The argument is a **comparison of bargains**: publishers have a real\n// need; absent a fitted capability they will request `net:fetch` to satisfy it; and\n// a `net:fetch` grant obtained for analytics is a worse bargain for the user than an\n// analytics grant — broader reach, arbitrary bodies, and a consent line that says\n// \"network access\" rather than \"usage statistics\". An app holding BOTH is displayed\n// as such at consent, because the analytics grant then bounds nothing.\n//\n// ─────────────────────────────────────────────────────────────────────────────\n// WRITE-ONLY. THERE IS NO READ METHOD HERE, AND NONE IS COMING.\n// ─────────────────────────────────────────────────────────────────────────────\n//\n// T-AN-6. An app that could read its own aggregates would learn about the USER —\n// which is the party the architecture assumes is being protected from unaccountable\n// publishers. §13 records the read path as rejected: *\"a plausible feature that\n// converts a write-only channel into a two-way one, and would need its own threat\n// pass.\"* The wire family declares no push channel and no poll, so there is nothing\n// for a read method to ride on.\n//\n// The reply is a bare acknowledgement. It carries no count, no remaining budget, and\n// no \"was that route recognised\" — each of those would be a read channel by another\n// name, and an app that could probe which paths are accepted has one.\n//\n// ─────────────────────────────────────────────────────────────────────────────\n// WHAT YOU MUST DECLARE, AND WHY IT IS THE SHAPE IT IS\n// ─────────────────────────────────────────────────────────────────────────────\n//\n// Everything an app may emit is declared in its manifest and consented to by the\n// user. **The hash of that declaration is bound into the grant** (§2.1): change the\n// vocabulary and the grant is invalid until the user re-consents with the new one\n// shown. `appKey` carries no ref, so without that binding a publisher could observe\n// their aggregates and then ship an alphabet tuned to encode what they now want to\n// read, under a grant given for something else.\n//\n// \"capabilities\": [{\n// \"name\": \"analytics:emit\",\n// \"params\": {\n// \"events\": {\n// \"clinic.view\": { \"props\": { \"tab\": { \"type\": \"enum\", \"values\": [\"summary\", \"meds\"] } } },\n// \"clinic.export\": { \"props\": { \"format\": { \"type\": \"enum\", \"values\": [\"pdf\", \"csv\"] } } }\n// },\n// \"routes\": [\"/patients/:id\", \"/patients\"]\n// }\n// }]\n//\n// - **String properties must be bounded ENUMERATIONS**, never free strings; numeric\n// ones declare an INTEGRAL range. This is the difference between a bound that is\n// computed and one that is hoped for: analytics is a covert channel with a\n// capacity, and a free string carries the file, the key, the row. It will be the\n// first thing you want relaxed; §12 says so in advance.\n// - **The total declared vocabulary is capped** at 2^12 distinct emit-shapes. Eight\n// properties of sixteen values each looks modest written out and is 4.3 billion.\n// - **Routes are patterns, never paths.** `/patients/12345` is not a page name. You\n// pass the concrete path to {@link recordRoute} and the platform records\n// `/patients/:id`; the variable segment is discarded at the boundary and never\n// transmitted. If you need per-item counts, declare a bounded enumeration of\n// items — there is no unbounded per-item cardinality by design.\n// - **There is a per-user daily cap**, published in the consent line's detail.\n//\n// ─────────────────────────────────────────────────────────────────────────────\n// WHEN THIS WILL REFUSE\n// ─────────────────────────────────────────────────────────────────────────────\n//\n// Every refusal is a typed error, and none of them is retryable by trying harder:\n//\n// - `forbidden` — no grant; or the grant is bound to a DIFFERENT vocabulary than the\n// one currently declared (re-consent needed); or the app is running under the M3\n// stranger stance, which refuses `analytics:*` outright; or the caller is a task\n// app invoked by a holder — the capability is not delegable.\n// - `invalid-params` — the event is not in the declared vocabulary: an undeclared\n// name or key, a string outside its enumeration, a number outside its range.\n// Rejected, never silently stripped.\n// - `budget` — the per-(app, user) daily cap is spent.\n//\n// **Emits never throw into your app by default.** {@link track} swallows refusals,\n// because an analytics call failing is not a reason for a feature to fail. Use\n// {@link emitAnalyticsEvent} when you want the error.\n\nimport { protocolRequest } from './sandboxUtils';\nimport { SCHEMES } from './protocolSchemes';\nimport { PROTOCOL_ANALYTICS } from './generated/protocol';\n\n/** Property values a declared event may carry. Scalars only — an object or an array\n * has no bound, and the bound is the point. */\nexport type AnalyticsPropValue = string | number | boolean;\n\n/** The acknowledgement. Deliberately carries nothing but the fact of acceptance —\n * anything else would be a read channel back into the app (T-AN-6). */\nexport interface AnalyticsAck {\n accepted: boolean;\n}\n\n/**\n * Emit one declared analytics event, surfacing refusals as typed errors.\n *\n * @param name a declared, app-namespaced event name (`myapp.somethingHappened`).\n * It may not collide with the host vocabulary.\n * @param props declared properties only. An undeclared key REJECTS the event —\n * nothing is stripped, because a silently dropped key turns a leak into\n * a green test.\n *\n * @throws `forbidden` | `invalid-params` | `budget` — see the module header.\n */\nexport const emitAnalyticsEvent = (name: string, props?: Record<string, AnalyticsPropValue>): Promise<AnalyticsAck> =>\n protocolRequest(SCHEMES[PROTOCOL_ANALYTICS], 'emit', [{ name, ...(props ? { props } : {}) }]);\n\n/**\n * Record a navigation, as a declared route PATTERN.\n *\n * Pass the concrete path your router produced. The platform matches it against your\n * declared patterns and records the **pattern**: `/patients/12345` becomes\n * `/patients/:id`, and the id is discarded at the boundary rather than filtered\n * later. A path matching no declared pattern records nothing — and reports success\n * either way, because telling you which paths are accepted would be a read channel.\n *\n * @throws the same typed errors as {@link emitAnalyticsEvent}.\n */\nexport const recordRoute = (path: string): Promise<AnalyticsAck> =>\n protocolRequest(SCHEMES[PROTOCOL_ANALYTICS], 'route', [{ path }]);\n\n/**\n * Fire-and-forget {@link emitAnalyticsEvent}.\n *\n * Swallows every refusal, because an analytics call failing is not a reason for a\n * feature to fail — and because the alternative is every call site wrapping this in\n * a `try` that does nothing, which is the same behaviour with more places to get it\n * wrong. Use {@link emitAnalyticsEvent} while you are getting your vocabulary right;\n * use this in the code you ship.\n */\nexport const track = (name: string, props?: Record<string, AnalyticsPropValue>): void => {\n void emitAnalyticsEvent(name, props).catch(() => {});\n};\n\n/** Fire-and-forget {@link recordRoute}, on the same reasoning as {@link track}. */\nexport const trackRoute = (path: string): void => {\n void recordRoute(path).catch(() => {});\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0FA,0BAAgC;AAChC,6BAAwB;AACxB,sBAAmC;AAuB5B,MAAM,qBAAqB,CAAC,MAAc,cAC/C,qCAAgB,+BAAQ,kCAAkB,GAAG,QAAQ,CAAC,EAAE,MAAM,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC,EAAG,CAAC,CAAC;AAavF,MAAM,cAAc,CAAC,aAC1B,qCAAgB,+BAAQ,kCAAkB,GAAG,SAAS,CAAC,EAAE,KAAK,CAAC,CAAC;AAW3D,MAAM,QAAQ,CAAC,MAAc,UAAqD;AACvF,OAAK,mBAAmB,MAAM,KAAK,EAAE,MAAM,MAAM;AAAA,EAAC,CAAC;AACrD;AAGO,MAAM,aAAa,CAAC,SAAuB;AAChD,OAAK,YAAY,IAAI,EAAE,MAAM,MAAM;AAAA,EAAC,CAAC;AACvC;","names":[]}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/** Property values a declared event may carry. Scalars only — an object or an array
|
|
2
|
+
* has no bound, and the bound is the point. */
|
|
3
|
+
type AnalyticsPropValue = string | number | boolean;
|
|
4
|
+
/** The acknowledgement. Deliberately carries nothing but the fact of acceptance —
|
|
5
|
+
* anything else would be a read channel back into the app (T-AN-6). */
|
|
6
|
+
interface AnalyticsAck {
|
|
7
|
+
accepted: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Emit one declared analytics event, surfacing refusals as typed errors.
|
|
11
|
+
*
|
|
12
|
+
* @param name a declared, app-namespaced event name (`myapp.somethingHappened`).
|
|
13
|
+
* It may not collide with the host vocabulary.
|
|
14
|
+
* @param props declared properties only. An undeclared key REJECTS the event —
|
|
15
|
+
* nothing is stripped, because a silently dropped key turns a leak into
|
|
16
|
+
* a green test.
|
|
17
|
+
*
|
|
18
|
+
* @throws `forbidden` | `invalid-params` | `budget` — see the module header.
|
|
19
|
+
*/
|
|
20
|
+
declare const emitAnalyticsEvent: (name: string, props?: Record<string, AnalyticsPropValue>) => Promise<AnalyticsAck>;
|
|
21
|
+
/**
|
|
22
|
+
* Record a navigation, as a declared route PATTERN.
|
|
23
|
+
*
|
|
24
|
+
* Pass the concrete path your router produced. The platform matches it against your
|
|
25
|
+
* declared patterns and records the **pattern**: `/patients/12345` becomes
|
|
26
|
+
* `/patients/:id`, and the id is discarded at the boundary rather than filtered
|
|
27
|
+
* later. A path matching no declared pattern records nothing — and reports success
|
|
28
|
+
* either way, because telling you which paths are accepted would be a read channel.
|
|
29
|
+
*
|
|
30
|
+
* @throws the same typed errors as {@link emitAnalyticsEvent}.
|
|
31
|
+
*/
|
|
32
|
+
declare const recordRoute: (path: string) => Promise<AnalyticsAck>;
|
|
33
|
+
/**
|
|
34
|
+
* Fire-and-forget {@link emitAnalyticsEvent}.
|
|
35
|
+
*
|
|
36
|
+
* Swallows every refusal, because an analytics call failing is not a reason for a
|
|
37
|
+
* feature to fail — and because the alternative is every call site wrapping this in
|
|
38
|
+
* a `try` that does nothing, which is the same behaviour with more places to get it
|
|
39
|
+
* wrong. Use {@link emitAnalyticsEvent} while you are getting your vocabulary right;
|
|
40
|
+
* use this in the code you ship.
|
|
41
|
+
*/
|
|
42
|
+
declare const track: (name: string, props?: Record<string, AnalyticsPropValue>) => void;
|
|
43
|
+
/** Fire-and-forget {@link recordRoute}, on the same reasoning as {@link track}. */
|
|
44
|
+
declare const trackRoute: (path: string) => void;
|
|
45
|
+
|
|
46
|
+
export { type AnalyticsAck, type AnalyticsPropValue, emitAnalyticsEvent, recordRoute, track, trackRoute };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/** Property values a declared event may carry. Scalars only — an object or an array
|
|
2
|
+
* has no bound, and the bound is the point. */
|
|
3
|
+
type AnalyticsPropValue = string | number | boolean;
|
|
4
|
+
/** The acknowledgement. Deliberately carries nothing but the fact of acceptance —
|
|
5
|
+
* anything else would be a read channel back into the app (T-AN-6). */
|
|
6
|
+
interface AnalyticsAck {
|
|
7
|
+
accepted: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Emit one declared analytics event, surfacing refusals as typed errors.
|
|
11
|
+
*
|
|
12
|
+
* @param name a declared, app-namespaced event name (`myapp.somethingHappened`).
|
|
13
|
+
* It may not collide with the host vocabulary.
|
|
14
|
+
* @param props declared properties only. An undeclared key REJECTS the event —
|
|
15
|
+
* nothing is stripped, because a silently dropped key turns a leak into
|
|
16
|
+
* a green test.
|
|
17
|
+
*
|
|
18
|
+
* @throws `forbidden` | `invalid-params` | `budget` — see the module header.
|
|
19
|
+
*/
|
|
20
|
+
declare const emitAnalyticsEvent: (name: string, props?: Record<string, AnalyticsPropValue>) => Promise<AnalyticsAck>;
|
|
21
|
+
/**
|
|
22
|
+
* Record a navigation, as a declared route PATTERN.
|
|
23
|
+
*
|
|
24
|
+
* Pass the concrete path your router produced. The platform matches it against your
|
|
25
|
+
* declared patterns and records the **pattern**: `/patients/12345` becomes
|
|
26
|
+
* `/patients/:id`, and the id is discarded at the boundary rather than filtered
|
|
27
|
+
* later. A path matching no declared pattern records nothing — and reports success
|
|
28
|
+
* either way, because telling you which paths are accepted would be a read channel.
|
|
29
|
+
*
|
|
30
|
+
* @throws the same typed errors as {@link emitAnalyticsEvent}.
|
|
31
|
+
*/
|
|
32
|
+
declare const recordRoute: (path: string) => Promise<AnalyticsAck>;
|
|
33
|
+
/**
|
|
34
|
+
* Fire-and-forget {@link emitAnalyticsEvent}.
|
|
35
|
+
*
|
|
36
|
+
* Swallows every refusal, because an analytics call failing is not a reason for a
|
|
37
|
+
* feature to fail — and because the alternative is every call site wrapping this in
|
|
38
|
+
* a `try` that does nothing, which is the same behaviour with more places to get it
|
|
39
|
+
* wrong. Use {@link emitAnalyticsEvent} while you are getting your vocabulary right;
|
|
40
|
+
* use this in the code you ship.
|
|
41
|
+
*/
|
|
42
|
+
declare const track: (name: string, props?: Record<string, AnalyticsPropValue>) => void;
|
|
43
|
+
/** Fire-and-forget {@link recordRoute}, on the same reasoning as {@link track}. */
|
|
44
|
+
declare const trackRoute: (path: string) => void;
|
|
45
|
+
|
|
46
|
+
export { type AnalyticsAck, type AnalyticsPropValue, emitAnalyticsEvent, recordRoute, track, trackRoute };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import "./chunk-VHAA22YE.js";
|
|
2
|
+
import { protocolRequest } from "./sandboxUtils";
|
|
3
|
+
import { SCHEMES } from "./protocolSchemes";
|
|
4
|
+
import { PROTOCOL_ANALYTICS } from "./generated/protocol";
|
|
5
|
+
const emitAnalyticsEvent = (name, props) => protocolRequest(SCHEMES[PROTOCOL_ANALYTICS], "emit", [{ name, ...props ? { props } : {} }]);
|
|
6
|
+
const recordRoute = (path) => protocolRequest(SCHEMES[PROTOCOL_ANALYTICS], "route", [{ path }]);
|
|
7
|
+
const track = (name, props) => {
|
|
8
|
+
void emitAnalyticsEvent(name, props).catch(() => {
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
const trackRoute = (path) => {
|
|
12
|
+
void recordRoute(path).catch(() => {
|
|
13
|
+
});
|
|
14
|
+
};
|
|
15
|
+
export {
|
|
16
|
+
emitAnalyticsEvent,
|
|
17
|
+
recordRoute,
|
|
18
|
+
track,
|
|
19
|
+
trackRoute
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=analytics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/analytics.ts"],"sourcesContent":["// App analytics — the app-facing surface for `analytics:emit`\n// (APP_ANALYTICS_SPEC §2/§3/§5, roadmap R3-350).\n//\n// ─────────────────────────────────────────────────────────────────────────────\n// WHAT THIS IS FOR, STATED HONESTLY\n// ─────────────────────────────────────────────────────────────────────────────\n//\n// An app runs in an opaque-origin sandboxed iframe where even touching\n// `localStorage` throws. It has no storage and no identity of its own, so **a\n// publisher has no way to learn how their app is used.**\n//\n// The honest argument for this capability is *not* that it displaces `net:fetch` —\n// it does not displace anything, and nothing here narrows or discourages\n// `net:fetch`. The argument is a **comparison of bargains**: publishers have a real\n// need; absent a fitted capability they will request `net:fetch` to satisfy it; and\n// a `net:fetch` grant obtained for analytics is a worse bargain for the user than an\n// analytics grant — broader reach, arbitrary bodies, and a consent line that says\n// \"network access\" rather than \"usage statistics\". An app holding BOTH is displayed\n// as such at consent, because the analytics grant then bounds nothing.\n//\n// ─────────────────────────────────────────────────────────────────────────────\n// WRITE-ONLY. THERE IS NO READ METHOD HERE, AND NONE IS COMING.\n// ─────────────────────────────────────────────────────────────────────────────\n//\n// T-AN-6. An app that could read its own aggregates would learn about the USER —\n// which is the party the architecture assumes is being protected from unaccountable\n// publishers. §13 records the read path as rejected: *\"a plausible feature that\n// converts a write-only channel into a two-way one, and would need its own threat\n// pass.\"* The wire family declares no push channel and no poll, so there is nothing\n// for a read method to ride on.\n//\n// The reply is a bare acknowledgement. It carries no count, no remaining budget, and\n// no \"was that route recognised\" — each of those would be a read channel by another\n// name, and an app that could probe which paths are accepted has one.\n//\n// ─────────────────────────────────────────────────────────────────────────────\n// WHAT YOU MUST DECLARE, AND WHY IT IS THE SHAPE IT IS\n// ─────────────────────────────────────────────────────────────────────────────\n//\n// Everything an app may emit is declared in its manifest and consented to by the\n// user. **The hash of that declaration is bound into the grant** (§2.1): change the\n// vocabulary and the grant is invalid until the user re-consents with the new one\n// shown. `appKey` carries no ref, so without that binding a publisher could observe\n// their aggregates and then ship an alphabet tuned to encode what they now want to\n// read, under a grant given for something else.\n//\n// \"capabilities\": [{\n// \"name\": \"analytics:emit\",\n// \"params\": {\n// \"events\": {\n// \"clinic.view\": { \"props\": { \"tab\": { \"type\": \"enum\", \"values\": [\"summary\", \"meds\"] } } },\n// \"clinic.export\": { \"props\": { \"format\": { \"type\": \"enum\", \"values\": [\"pdf\", \"csv\"] } } }\n// },\n// \"routes\": [\"/patients/:id\", \"/patients\"]\n// }\n// }]\n//\n// - **String properties must be bounded ENUMERATIONS**, never free strings; numeric\n// ones declare an INTEGRAL range. This is the difference between a bound that is\n// computed and one that is hoped for: analytics is a covert channel with a\n// capacity, and a free string carries the file, the key, the row. It will be the\n// first thing you want relaxed; §12 says so in advance.\n// - **The total declared vocabulary is capped** at 2^12 distinct emit-shapes. Eight\n// properties of sixteen values each looks modest written out and is 4.3 billion.\n// - **Routes are patterns, never paths.** `/patients/12345` is not a page name. You\n// pass the concrete path to {@link recordRoute} and the platform records\n// `/patients/:id`; the variable segment is discarded at the boundary and never\n// transmitted. If you need per-item counts, declare a bounded enumeration of\n// items — there is no unbounded per-item cardinality by design.\n// - **There is a per-user daily cap**, published in the consent line's detail.\n//\n// ─────────────────────────────────────────────────────────────────────────────\n// WHEN THIS WILL REFUSE\n// ─────────────────────────────────────────────────────────────────────────────\n//\n// Every refusal is a typed error, and none of them is retryable by trying harder:\n//\n// - `forbidden` — no grant; or the grant is bound to a DIFFERENT vocabulary than the\n// one currently declared (re-consent needed); or the app is running under the M3\n// stranger stance, which refuses `analytics:*` outright; or the caller is a task\n// app invoked by a holder — the capability is not delegable.\n// - `invalid-params` — the event is not in the declared vocabulary: an undeclared\n// name or key, a string outside its enumeration, a number outside its range.\n// Rejected, never silently stripped.\n// - `budget` — the per-(app, user) daily cap is spent.\n//\n// **Emits never throw into your app by default.** {@link track} swallows refusals,\n// because an analytics call failing is not a reason for a feature to fail. Use\n// {@link emitAnalyticsEvent} when you want the error.\n\nimport { protocolRequest } from './sandboxUtils';\nimport { SCHEMES } from './protocolSchemes';\nimport { PROTOCOL_ANALYTICS } from './generated/protocol';\n\n/** Property values a declared event may carry. Scalars only — an object or an array\n * has no bound, and the bound is the point. */\nexport type AnalyticsPropValue = string | number | boolean;\n\n/** The acknowledgement. Deliberately carries nothing but the fact of acceptance —\n * anything else would be a read channel back into the app (T-AN-6). */\nexport interface AnalyticsAck {\n accepted: boolean;\n}\n\n/**\n * Emit one declared analytics event, surfacing refusals as typed errors.\n *\n * @param name a declared, app-namespaced event name (`myapp.somethingHappened`).\n * It may not collide with the host vocabulary.\n * @param props declared properties only. An undeclared key REJECTS the event —\n * nothing is stripped, because a silently dropped key turns a leak into\n * a green test.\n *\n * @throws `forbidden` | `invalid-params` | `budget` — see the module header.\n */\nexport const emitAnalyticsEvent = (name: string, props?: Record<string, AnalyticsPropValue>): Promise<AnalyticsAck> =>\n protocolRequest(SCHEMES[PROTOCOL_ANALYTICS], 'emit', [{ name, ...(props ? { props } : {}) }]);\n\n/**\n * Record a navigation, as a declared route PATTERN.\n *\n * Pass the concrete path your router produced. The platform matches it against your\n * declared patterns and records the **pattern**: `/patients/12345` becomes\n * `/patients/:id`, and the id is discarded at the boundary rather than filtered\n * later. A path matching no declared pattern records nothing — and reports success\n * either way, because telling you which paths are accepted would be a read channel.\n *\n * @throws the same typed errors as {@link emitAnalyticsEvent}.\n */\nexport const recordRoute = (path: string): Promise<AnalyticsAck> =>\n protocolRequest(SCHEMES[PROTOCOL_ANALYTICS], 'route', [{ path }]);\n\n/**\n * Fire-and-forget {@link emitAnalyticsEvent}.\n *\n * Swallows every refusal, because an analytics call failing is not a reason for a\n * feature to fail — and because the alternative is every call site wrapping this in\n * a `try` that does nothing, which is the same behaviour with more places to get it\n * wrong. Use {@link emitAnalyticsEvent} while you are getting your vocabulary right;\n * use this in the code you ship.\n */\nexport const track = (name: string, props?: Record<string, AnalyticsPropValue>): void => {\n void emitAnalyticsEvent(name, props).catch(() => {});\n};\n\n/** Fire-and-forget {@link recordRoute}, on the same reasoning as {@link track}. */\nexport const trackRoute = (path: string): void => {\n void recordRoute(path).catch(() => {});\n};\n"],"mappings":";AA0FA,SAAS,uBAAuB;AAChC,SAAS,eAAe;AACxB,SAAS,0BAA0B;AAuB5B,MAAM,qBAAqB,CAAC,MAAc,UAC/C,gBAAgB,QAAQ,kBAAkB,GAAG,QAAQ,CAAC,EAAE,MAAM,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC,EAAG,CAAC,CAAC;AAavF,MAAM,cAAc,CAAC,SAC1B,gBAAgB,QAAQ,kBAAkB,GAAG,SAAS,CAAC,EAAE,KAAK,CAAC,CAAC;AAW3D,MAAM,QAAQ,CAAC,MAAc,UAAqD;AACvF,OAAK,mBAAmB,MAAM,KAAK,EAAE,MAAM,MAAM;AAAA,EAAC,CAAC;AACrD;AAGO,MAAM,aAAa,CAAC,SAAuB;AAChD,OAAK,YAAY,IAAI,EAAE,MAAM,MAAM;AAAA,EAAC,CAAC;AACvC;","names":[]}
|
package/dist/corpus.cjs
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var corpus_exports = {};
|
|
20
|
+
__export(corpus_exports, {
|
|
21
|
+
CorpusContext: () => CorpusContext,
|
|
22
|
+
fromCorpusPath: () => fromCorpusPath,
|
|
23
|
+
toCorpusPath: () => toCorpusPath,
|
|
24
|
+
useCorpus: () => useCorpus,
|
|
25
|
+
useCorpusEntries: () => useCorpusEntries,
|
|
26
|
+
useCorpusEntry: () => useCorpusEntry,
|
|
27
|
+
useCurrentEntry: () => useCurrentEntry
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(corpus_exports);
|
|
30
|
+
var import_react = require("react");
|
|
31
|
+
var import_metadataSource = require("./metadataSource");
|
|
32
|
+
const EMPTY_SCOPE = { root: null, entry: null, toHref: (p) => p };
|
|
33
|
+
const CorpusContext = (0, import_react.createContext)(EMPTY_SCOPE);
|
|
34
|
+
const useCorpus = () => (0, import_react.use)(CorpusContext);
|
|
35
|
+
const toCorpusPath = (absolute, root) => {
|
|
36
|
+
if (root === null) return null;
|
|
37
|
+
const base = root.replace(/\/+$/, "");
|
|
38
|
+
if (base === "") return absolute;
|
|
39
|
+
if (!absolute.startsWith(`${base}/`)) return null;
|
|
40
|
+
return absolute.slice(base.length);
|
|
41
|
+
};
|
|
42
|
+
const fromCorpusPath = (corpusPath, root) => {
|
|
43
|
+
if (root === null) return null;
|
|
44
|
+
const base = root.replace(/\/+$/, "");
|
|
45
|
+
return `${base}${corpusPath.startsWith("/") ? "" : "/"}${corpusPath}`;
|
|
46
|
+
};
|
|
47
|
+
const useCorpusEntries = () => {
|
|
48
|
+
const files = (0, import_metadataSource.useMetadataStore)();
|
|
49
|
+
const { root, toHref } = useCorpus();
|
|
50
|
+
return (0, import_react.useMemo)(() => {
|
|
51
|
+
if (root === null) return [];
|
|
52
|
+
const out = [];
|
|
53
|
+
for (const [absolute, meta] of Object.entries(files)) {
|
|
54
|
+
const path = toCorpusPath(absolute, root);
|
|
55
|
+
if (path === null) continue;
|
|
56
|
+
out.push({ path, href: toHref(path), meta });
|
|
57
|
+
}
|
|
58
|
+
out.sort((a, b) => a.path.localeCompare(b.path));
|
|
59
|
+
return out;
|
|
60
|
+
}, [files, root, toHref]);
|
|
61
|
+
};
|
|
62
|
+
const useCorpusEntry = (corpusPath) => {
|
|
63
|
+
const files = (0, import_metadataSource.useMetadataStore)();
|
|
64
|
+
const { root } = useCorpus();
|
|
65
|
+
return (0, import_react.useMemo)(() => {
|
|
66
|
+
const absolute = fromCorpusPath(corpusPath, root);
|
|
67
|
+
return absolute === null ? void 0 : files[absolute];
|
|
68
|
+
}, [corpusPath, files, root]);
|
|
69
|
+
};
|
|
70
|
+
const useCurrentEntry = () => {
|
|
71
|
+
const files = (0, import_metadataSource.useMetadataStore)();
|
|
72
|
+
const { root, entry, toHref } = useCorpus();
|
|
73
|
+
return (0, import_react.useMemo)(() => {
|
|
74
|
+
if (root === null || entry === null) return null;
|
|
75
|
+
const absolute = fromCorpusPath(entry, root);
|
|
76
|
+
const meta = absolute === null ? void 0 : files[absolute];
|
|
77
|
+
if (meta === void 0) return null;
|
|
78
|
+
return { path: entry, href: toHref(entry), meta };
|
|
79
|
+
}, [files, root, entry, toHref]);
|
|
80
|
+
};
|
|
81
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
82
|
+
0 && (module.exports = {
|
|
83
|
+
CorpusContext,
|
|
84
|
+
fromCorpusPath,
|
|
85
|
+
toCorpusPath,
|
|
86
|
+
useCorpus,
|
|
87
|
+
useCorpusEntries,
|
|
88
|
+
useCorpusEntry,
|
|
89
|
+
useCurrentEntry
|
|
90
|
+
});
|
|
91
|
+
//# sourceMappingURL=corpus.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/corpus.ts"],"sourcesContent":["// The corpus scope — what a component rendered INSIDE a corpus may know about it\n// (R3-174; MDX_FROM_MOUNT_SPEC §2, §7 1a).\n//\n// A corpus viewer can register components the corpus itself ships, so an entry writes\n// `<ProjectIndex/>` and the viewer resolves it — no engine fork, no import line\n// (`MDX_FROM_MOUNT_SPEC` §2's \"provider composition is consumer policy\"). Those components\n// live in the CONTENT filesystem and the viewer lives in its own, and the seam between\n// them is this package: a content component cannot import the viewer (it would resolve a\n// second copy from the registry, with its own module state, and read the wrong corpus), so\n// anything the viewer must tell it has to arrive through a surface both sides already\n// share. This is that surface.\n//\n// **Why paths here are corpus-absolute, not filesystem-absolute.** The metadata store is\n// keyed by absolute module path, which under dispatch means `/mnt/<hash>/roadmap/x.mdx` —\n// the host-minted chroot. That prefix is host knowledge a viewer may read THROUGH but must\n// never publish (the property `grove/src/components/DirectoryList.test.tsx` pins with\n// `expect(el.innerHTML).not.toContain('mnt')`), and it is not stable across loads. A\n// content component that saw it would embed it in hrefs and keys. So the corpus scope\n// rebases every path it hands out to the corpus root (`/roadmap/x.mdx`), which is the same\n// address under fork, library and dispatch composition — `PLATFORM_LAYERING_SPEC` §1.1's\n// mode-invariance rule, applied to metadata rather than to links.\n//\n// **Why the href mapping is injected rather than derived.** Corpus path → in-app URL is\n// VIEWER policy, and the two packagings genuinely disagree (a fork's URLs are anchored at\n// its app root and are already published and cited; a dispatched viewer's are corpus-\n// relative). A content component must not have to know which it is in, and the SDK must\n// not guess — so the viewer supplies `toHref` and content never computes a URL itself.\n\nimport { createContext, use, useMemo } from 'react';\nimport { useMetadataStore } from './metadataSource';\nimport type { Metadata } from './sandboxTypes';\n\n/** What a corpus viewer declares about the corpus it is rendering. */\nexport interface CorpusScope {\n /**\n * Absolute filesystem path of the corpus root, WITHOUT a trailing slash\n * (`/app/content` in a fork, `/mnt/<hash>` under dispatch), or `null` when the\n * surrounding app is not rendering a corpus — the default, which leaves every hook here\n * returning the empty result rather than guessing a root.\n */\n root: string | null;\n /** Corpus-absolute path of the entry currently being read (`/roadmap/R3-174.mdx`), or\n * `null` when nothing is. This is the entry, NOT the file being rendered: a component\n * in a `_layout.mdx` wrapping that entry sees the entry, which is what makes furniture\n * in the layout chain (a status line, a dependency rail) able to describe the page. */\n entry: string | null;\n /** Corpus-absolute path → the href to navigate to it. Supplied by the viewer; the\n * identity function by default, which is correct for a viewer whose URL space IS the\n * corpus space. */\n toHref: (corpusPath: string) => string;\n}\n\nconst EMPTY_SCOPE: CorpusScope = { root: null, entry: null, toHref: (p) => p };\n\n/** Ambient corpus scope. A corpus-rendering app wraps its content tree in\n * `<CorpusContext value={{ root, entry, toHref }}>`; nesting a second provider inside a\n * rendered sub-corpus makes the innermost win, as with {@link LinkSpaceContext}. */\nexport const CorpusContext = createContext<CorpusScope>(EMPTY_SCOPE);\n\n/** Read the ambient corpus scope. Every hook below is a convenience over this. */\nexport const useCorpus = (): CorpusScope => use(CorpusContext);\n\n/**\n * Filesystem-absolute path → corpus-absolute, or `null` when the path is not inside the\n * corpus. Exact-root and separator-boundary aware, so `/mnt/hash2/x` is not treated as\n * living under `/mnt/hash`.\n */\nexport const toCorpusPath = (absolute: string, root: string | null): string | null => {\n if (root === null) return null;\n const base = root.replace(/\\/+$/, '');\n if (base === '') return absolute;\n if (!absolute.startsWith(`${base}/`)) return null;\n return absolute.slice(base.length);\n};\n\n/** Corpus-absolute path → filesystem-absolute, or `null` without a root. The inverse of\n * {@link toCorpusPath}, for the rare content component that must read raw bytes. */\nexport const fromCorpusPath = (corpusPath: string, root: string | null): string | null => {\n if (root === null) return null;\n const base = root.replace(/\\/+$/, '');\n return `${base}${corpusPath.startsWith('/') ? '' : '/'}${corpusPath}`;\n};\n\n/** One entry as content sees it: where it is, where it links, and its frontmatter. */\nexport interface CorpusEntry<T = Metadata> {\n /** Corpus-absolute path (`/roadmap/R3-174.mdx`). */\n path: string;\n /** The href that navigates to it, per the viewer's mapping. */\n href: string;\n meta: T;\n}\n\n/**\n * Every entry in the surrounding corpus, with corpus-absolute paths and viewer-supplied\n * hrefs — the surface a content component queries instead of {@link useMetadataQuery},\n * whose keys are filesystem-absolute and therefore carry the mount prefix.\n *\n * Returns an empty array outside a corpus, so a component written for a corpus renders\n * nothing rather than throwing when someone drops it elsewhere. The array keeps its\n * identity while the store and root are unchanged, so it is safe in dependency arrays.\n */\nexport const useCorpusEntries = <T = Metadata>(): CorpusEntry<T>[] => {\n const files = useMetadataStore<T>();\n const { root, toHref } = useCorpus();\n return useMemo(() => {\n if (root === null) return [];\n const out: CorpusEntry<T>[] = [];\n for (const [absolute, meta] of Object.entries(files)) {\n const path = toCorpusPath(absolute, root);\n if (path === null) continue;\n out.push({ path, href: toHref(path), meta: meta as T });\n }\n // Path order, so a consumer that does not sort still renders deterministically\n // (object key order is insertion order, which is scan order, which is not stable).\n out.sort((a, b) => a.path.localeCompare(b.path));\n return out;\n }, [files, root, toHref]);\n};\n\n/** One entry's frontmatter by corpus-absolute path, or `undefined`. */\nexport const useCorpusEntry = <T = Metadata>(corpusPath: string): T | undefined => {\n const files = useMetadataStore<T>();\n const { root } = useCorpus();\n return useMemo(() => {\n const absolute = fromCorpusPath(corpusPath, root);\n return absolute === null ? undefined : files[absolute];\n }, [corpusPath, files, root]);\n};\n\n/** The entry currently being read — `null` outside a corpus, or when the viewer declares\n * no entry (a directory listing, a 404). See {@link CorpusScope.entry} for why this is\n * the entry rather than the file the component happens to be written in. */\nexport const useCurrentEntry = <T = Metadata>(): CorpusEntry<T> | null => {\n const files = useMetadataStore<T>();\n const { root, entry, toHref } = useCorpus();\n return useMemo(() => {\n if (root === null || entry === null) return null;\n const absolute = fromCorpusPath(entry, root);\n const meta = absolute === null ? undefined : files[absolute];\n if (meta === undefined) return null;\n return { path: entry, href: toHref(entry), meta: meta as T };\n }, [files, root, entry, toHref]);\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA4BA,mBAA4C;AAC5C,4BAAiC;AAuBjC,MAAM,cAA2B,EAAE,MAAM,MAAM,OAAO,MAAM,QAAQ,CAAC,MAAM,EAAE;AAKtE,MAAM,oBAAgB,4BAA2B,WAAW;AAG5D,MAAM,YAAY,UAAmB,kBAAI,aAAa;AAOtD,MAAM,eAAe,CAAC,UAAkB,SAAuC;AACpF,MAAI,SAAS,KAAM,QAAO;AAC1B,QAAM,OAAO,KAAK,QAAQ,QAAQ,EAAE;AACpC,MAAI,SAAS,GAAI,QAAO;AACxB,MAAI,CAAC,SAAS,WAAW,GAAG,IAAI,GAAG,EAAG,QAAO;AAC7C,SAAO,SAAS,MAAM,KAAK,MAAM;AACnC;AAIO,MAAM,iBAAiB,CAAC,YAAoB,SAAuC;AACxF,MAAI,SAAS,KAAM,QAAO;AAC1B,QAAM,OAAO,KAAK,QAAQ,QAAQ,EAAE;AACpC,SAAO,GAAG,IAAI,GAAG,WAAW,WAAW,GAAG,IAAI,KAAK,GAAG,GAAG,UAAU;AACrE;AAoBO,MAAM,mBAAmB,MAAsC;AACpE,QAAM,YAAQ,wCAAoB;AAClC,QAAM,EAAE,MAAM,OAAO,IAAI,UAAU;AACnC,aAAO,sBAAQ,MAAM;AACnB,QAAI,SAAS,KAAM,QAAO,CAAC;AAC3B,UAAM,MAAwB,CAAC;AAC/B,eAAW,CAAC,UAAU,IAAI,KAAK,OAAO,QAAQ,KAAK,GAAG;AACpD,YAAM,OAAO,aAAa,UAAU,IAAI;AACxC,UAAI,SAAS,KAAM;AACnB,UAAI,KAAK,EAAE,MAAM,MAAM,OAAO,IAAI,GAAG,KAAgB,CAAC;AAAA,IACxD;AAGA,QAAI,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AAC/C,WAAO;AAAA,EACT,GAAG,CAAC,OAAO,MAAM,MAAM,CAAC;AAC1B;AAGO,MAAM,iBAAiB,CAAe,eAAsC;AACjF,QAAM,YAAQ,wCAAoB;AAClC,QAAM,EAAE,KAAK,IAAI,UAAU;AAC3B,aAAO,sBAAQ,MAAM;AACnB,UAAM,WAAW,eAAe,YAAY,IAAI;AAChD,WAAO,aAAa,OAAO,SAAY,MAAM,QAAQ;AAAA,EACvD,GAAG,CAAC,YAAY,OAAO,IAAI,CAAC;AAC9B;AAKO,MAAM,kBAAkB,MAA2C;AACxE,QAAM,YAAQ,wCAAoB;AAClC,QAAM,EAAE,MAAM,OAAO,OAAO,IAAI,UAAU;AAC1C,aAAO,sBAAQ,MAAM;AACnB,QAAI,SAAS,QAAQ,UAAU,KAAM,QAAO;AAC5C,UAAM,WAAW,eAAe,OAAO,IAAI;AAC3C,UAAM,OAAO,aAAa,OAAO,SAAY,MAAM,QAAQ;AAC3D,QAAI,SAAS,OAAW,QAAO;AAC/B,WAAO,EAAE,MAAM,OAAO,MAAM,OAAO,KAAK,GAAG,KAAgB;AAAA,EAC7D,GAAG,CAAC,OAAO,MAAM,OAAO,MAAM,CAAC;AACjC;","names":[]}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { Metadata } from './sandboxTypes.cjs';
|
|
3
|
+
|
|
4
|
+
/** What a corpus viewer declares about the corpus it is rendering. */
|
|
5
|
+
interface CorpusScope {
|
|
6
|
+
/**
|
|
7
|
+
* Absolute filesystem path of the corpus root, WITHOUT a trailing slash
|
|
8
|
+
* (`/app/content` in a fork, `/mnt/<hash>` under dispatch), or `null` when the
|
|
9
|
+
* surrounding app is not rendering a corpus — the default, which leaves every hook here
|
|
10
|
+
* returning the empty result rather than guessing a root.
|
|
11
|
+
*/
|
|
12
|
+
root: string | null;
|
|
13
|
+
/** Corpus-absolute path of the entry currently being read (`/roadmap/R3-174.mdx`), or
|
|
14
|
+
* `null` when nothing is. This is the entry, NOT the file being rendered: a component
|
|
15
|
+
* in a `_layout.mdx` wrapping that entry sees the entry, which is what makes furniture
|
|
16
|
+
* in the layout chain (a status line, a dependency rail) able to describe the page. */
|
|
17
|
+
entry: string | null;
|
|
18
|
+
/** Corpus-absolute path → the href to navigate to it. Supplied by the viewer; the
|
|
19
|
+
* identity function by default, which is correct for a viewer whose URL space IS the
|
|
20
|
+
* corpus space. */
|
|
21
|
+
toHref: (corpusPath: string) => string;
|
|
22
|
+
}
|
|
23
|
+
/** Ambient corpus scope. A corpus-rendering app wraps its content tree in
|
|
24
|
+
* `<CorpusContext value={{ root, entry, toHref }}>`; nesting a second provider inside a
|
|
25
|
+
* rendered sub-corpus makes the innermost win, as with {@link LinkSpaceContext}. */
|
|
26
|
+
declare const CorpusContext: react.Context<CorpusScope>;
|
|
27
|
+
/** Read the ambient corpus scope. Every hook below is a convenience over this. */
|
|
28
|
+
declare const useCorpus: () => CorpusScope;
|
|
29
|
+
/**
|
|
30
|
+
* Filesystem-absolute path → corpus-absolute, or `null` when the path is not inside the
|
|
31
|
+
* corpus. Exact-root and separator-boundary aware, so `/mnt/hash2/x` is not treated as
|
|
32
|
+
* living under `/mnt/hash`.
|
|
33
|
+
*/
|
|
34
|
+
declare const toCorpusPath: (absolute: string, root: string | null) => string | null;
|
|
35
|
+
/** Corpus-absolute path → filesystem-absolute, or `null` without a root. The inverse of
|
|
36
|
+
* {@link toCorpusPath}, for the rare content component that must read raw bytes. */
|
|
37
|
+
declare const fromCorpusPath: (corpusPath: string, root: string | null) => string | null;
|
|
38
|
+
/** One entry as content sees it: where it is, where it links, and its frontmatter. */
|
|
39
|
+
interface CorpusEntry<T = Metadata> {
|
|
40
|
+
/** Corpus-absolute path (`/roadmap/R3-174.mdx`). */
|
|
41
|
+
path: string;
|
|
42
|
+
/** The href that navigates to it, per the viewer's mapping. */
|
|
43
|
+
href: string;
|
|
44
|
+
meta: T;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Every entry in the surrounding corpus, with corpus-absolute paths and viewer-supplied
|
|
48
|
+
* hrefs — the surface a content component queries instead of {@link useMetadataQuery},
|
|
49
|
+
* whose keys are filesystem-absolute and therefore carry the mount prefix.
|
|
50
|
+
*
|
|
51
|
+
* Returns an empty array outside a corpus, so a component written for a corpus renders
|
|
52
|
+
* nothing rather than throwing when someone drops it elsewhere. The array keeps its
|
|
53
|
+
* identity while the store and root are unchanged, so it is safe in dependency arrays.
|
|
54
|
+
*/
|
|
55
|
+
declare const useCorpusEntries: <T = Metadata>() => CorpusEntry<T>[];
|
|
56
|
+
/** One entry's frontmatter by corpus-absolute path, or `undefined`. */
|
|
57
|
+
declare const useCorpusEntry: <T = Metadata>(corpusPath: string) => T | undefined;
|
|
58
|
+
/** The entry currently being read — `null` outside a corpus, or when the viewer declares
|
|
59
|
+
* no entry (a directory listing, a 404). See {@link CorpusScope.entry} for why this is
|
|
60
|
+
* the entry rather than the file the component happens to be written in. */
|
|
61
|
+
declare const useCurrentEntry: <T = Metadata>() => CorpusEntry<T> | null;
|
|
62
|
+
|
|
63
|
+
export { CorpusContext, type CorpusEntry, type CorpusScope, fromCorpusPath, toCorpusPath, useCorpus, useCorpusEntries, useCorpusEntry, useCurrentEntry };
|
package/dist/corpus.d.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { Metadata } from './sandboxTypes.js';
|
|
3
|
+
|
|
4
|
+
/** What a corpus viewer declares about the corpus it is rendering. */
|
|
5
|
+
interface CorpusScope {
|
|
6
|
+
/**
|
|
7
|
+
* Absolute filesystem path of the corpus root, WITHOUT a trailing slash
|
|
8
|
+
* (`/app/content` in a fork, `/mnt/<hash>` under dispatch), or `null` when the
|
|
9
|
+
* surrounding app is not rendering a corpus — the default, which leaves every hook here
|
|
10
|
+
* returning the empty result rather than guessing a root.
|
|
11
|
+
*/
|
|
12
|
+
root: string | null;
|
|
13
|
+
/** Corpus-absolute path of the entry currently being read (`/roadmap/R3-174.mdx`), or
|
|
14
|
+
* `null` when nothing is. This is the entry, NOT the file being rendered: a component
|
|
15
|
+
* in a `_layout.mdx` wrapping that entry sees the entry, which is what makes furniture
|
|
16
|
+
* in the layout chain (a status line, a dependency rail) able to describe the page. */
|
|
17
|
+
entry: string | null;
|
|
18
|
+
/** Corpus-absolute path → the href to navigate to it. Supplied by the viewer; the
|
|
19
|
+
* identity function by default, which is correct for a viewer whose URL space IS the
|
|
20
|
+
* corpus space. */
|
|
21
|
+
toHref: (corpusPath: string) => string;
|
|
22
|
+
}
|
|
23
|
+
/** Ambient corpus scope. A corpus-rendering app wraps its content tree in
|
|
24
|
+
* `<CorpusContext value={{ root, entry, toHref }}>`; nesting a second provider inside a
|
|
25
|
+
* rendered sub-corpus makes the innermost win, as with {@link LinkSpaceContext}. */
|
|
26
|
+
declare const CorpusContext: react.Context<CorpusScope>;
|
|
27
|
+
/** Read the ambient corpus scope. Every hook below is a convenience over this. */
|
|
28
|
+
declare const useCorpus: () => CorpusScope;
|
|
29
|
+
/**
|
|
30
|
+
* Filesystem-absolute path → corpus-absolute, or `null` when the path is not inside the
|
|
31
|
+
* corpus. Exact-root and separator-boundary aware, so `/mnt/hash2/x` is not treated as
|
|
32
|
+
* living under `/mnt/hash`.
|
|
33
|
+
*/
|
|
34
|
+
declare const toCorpusPath: (absolute: string, root: string | null) => string | null;
|
|
35
|
+
/** Corpus-absolute path → filesystem-absolute, or `null` without a root. The inverse of
|
|
36
|
+
* {@link toCorpusPath}, for the rare content component that must read raw bytes. */
|
|
37
|
+
declare const fromCorpusPath: (corpusPath: string, root: string | null) => string | null;
|
|
38
|
+
/** One entry as content sees it: where it is, where it links, and its frontmatter. */
|
|
39
|
+
interface CorpusEntry<T = Metadata> {
|
|
40
|
+
/** Corpus-absolute path (`/roadmap/R3-174.mdx`). */
|
|
41
|
+
path: string;
|
|
42
|
+
/** The href that navigates to it, per the viewer's mapping. */
|
|
43
|
+
href: string;
|
|
44
|
+
meta: T;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Every entry in the surrounding corpus, with corpus-absolute paths and viewer-supplied
|
|
48
|
+
* hrefs — the surface a content component queries instead of {@link useMetadataQuery},
|
|
49
|
+
* whose keys are filesystem-absolute and therefore carry the mount prefix.
|
|
50
|
+
*
|
|
51
|
+
* Returns an empty array outside a corpus, so a component written for a corpus renders
|
|
52
|
+
* nothing rather than throwing when someone drops it elsewhere. The array keeps its
|
|
53
|
+
* identity while the store and root are unchanged, so it is safe in dependency arrays.
|
|
54
|
+
*/
|
|
55
|
+
declare const useCorpusEntries: <T = Metadata>() => CorpusEntry<T>[];
|
|
56
|
+
/** One entry's frontmatter by corpus-absolute path, or `undefined`. */
|
|
57
|
+
declare const useCorpusEntry: <T = Metadata>(corpusPath: string) => T | undefined;
|
|
58
|
+
/** The entry currently being read — `null` outside a corpus, or when the viewer declares
|
|
59
|
+
* no entry (a directory listing, a 404). See {@link CorpusScope.entry} for why this is
|
|
60
|
+
* the entry rather than the file the component happens to be written in. */
|
|
61
|
+
declare const useCurrentEntry: <T = Metadata>() => CorpusEntry<T> | null;
|
|
62
|
+
|
|
63
|
+
export { CorpusContext, type CorpusEntry, type CorpusScope, fromCorpusPath, toCorpusPath, useCorpus, useCorpusEntries, useCorpusEntry, useCurrentEntry };
|
package/dist/corpus.js
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import "./chunk-VHAA22YE.js";
|
|
2
|
+
import { createContext, use, useMemo } from "react";
|
|
3
|
+
import { useMetadataStore } from "./metadataSource";
|
|
4
|
+
const EMPTY_SCOPE = { root: null, entry: null, toHref: (p) => p };
|
|
5
|
+
const CorpusContext = createContext(EMPTY_SCOPE);
|
|
6
|
+
const useCorpus = () => use(CorpusContext);
|
|
7
|
+
const toCorpusPath = (absolute, root) => {
|
|
8
|
+
if (root === null) return null;
|
|
9
|
+
const base = root.replace(/\/+$/, "");
|
|
10
|
+
if (base === "") return absolute;
|
|
11
|
+
if (!absolute.startsWith(`${base}/`)) return null;
|
|
12
|
+
return absolute.slice(base.length);
|
|
13
|
+
};
|
|
14
|
+
const fromCorpusPath = (corpusPath, root) => {
|
|
15
|
+
if (root === null) return null;
|
|
16
|
+
const base = root.replace(/\/+$/, "");
|
|
17
|
+
return `${base}${corpusPath.startsWith("/") ? "" : "/"}${corpusPath}`;
|
|
18
|
+
};
|
|
19
|
+
const useCorpusEntries = () => {
|
|
20
|
+
const files = useMetadataStore();
|
|
21
|
+
const { root, toHref } = useCorpus();
|
|
22
|
+
return useMemo(() => {
|
|
23
|
+
if (root === null) return [];
|
|
24
|
+
const out = [];
|
|
25
|
+
for (const [absolute, meta] of Object.entries(files)) {
|
|
26
|
+
const path = toCorpusPath(absolute, root);
|
|
27
|
+
if (path === null) continue;
|
|
28
|
+
out.push({ path, href: toHref(path), meta });
|
|
29
|
+
}
|
|
30
|
+
out.sort((a, b) => a.path.localeCompare(b.path));
|
|
31
|
+
return out;
|
|
32
|
+
}, [files, root, toHref]);
|
|
33
|
+
};
|
|
34
|
+
const useCorpusEntry = (corpusPath) => {
|
|
35
|
+
const files = useMetadataStore();
|
|
36
|
+
const { root } = useCorpus();
|
|
37
|
+
return useMemo(() => {
|
|
38
|
+
const absolute = fromCorpusPath(corpusPath, root);
|
|
39
|
+
return absolute === null ? void 0 : files[absolute];
|
|
40
|
+
}, [corpusPath, files, root]);
|
|
41
|
+
};
|
|
42
|
+
const useCurrentEntry = () => {
|
|
43
|
+
const files = useMetadataStore();
|
|
44
|
+
const { root, entry, toHref } = useCorpus();
|
|
45
|
+
return useMemo(() => {
|
|
46
|
+
if (root === null || entry === null) return null;
|
|
47
|
+
const absolute = fromCorpusPath(entry, root);
|
|
48
|
+
const meta = absolute === null ? void 0 : files[absolute];
|
|
49
|
+
if (meta === void 0) return null;
|
|
50
|
+
return { path: entry, href: toHref(entry), meta };
|
|
51
|
+
}, [files, root, entry, toHref]);
|
|
52
|
+
};
|
|
53
|
+
export {
|
|
54
|
+
CorpusContext,
|
|
55
|
+
fromCorpusPath,
|
|
56
|
+
toCorpusPath,
|
|
57
|
+
useCorpus,
|
|
58
|
+
useCorpusEntries,
|
|
59
|
+
useCorpusEntry,
|
|
60
|
+
useCurrentEntry
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=corpus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/corpus.ts"],"sourcesContent":["// The corpus scope — what a component rendered INSIDE a corpus may know about it\n// (R3-174; MDX_FROM_MOUNT_SPEC §2, §7 1a).\n//\n// A corpus viewer can register components the corpus itself ships, so an entry writes\n// `<ProjectIndex/>` and the viewer resolves it — no engine fork, no import line\n// (`MDX_FROM_MOUNT_SPEC` §2's \"provider composition is consumer policy\"). Those components\n// live in the CONTENT filesystem and the viewer lives in its own, and the seam between\n// them is this package: a content component cannot import the viewer (it would resolve a\n// second copy from the registry, with its own module state, and read the wrong corpus), so\n// anything the viewer must tell it has to arrive through a surface both sides already\n// share. This is that surface.\n//\n// **Why paths here are corpus-absolute, not filesystem-absolute.** The metadata store is\n// keyed by absolute module path, which under dispatch means `/mnt/<hash>/roadmap/x.mdx` —\n// the host-minted chroot. That prefix is host knowledge a viewer may read THROUGH but must\n// never publish (the property `grove/src/components/DirectoryList.test.tsx` pins with\n// `expect(el.innerHTML).not.toContain('mnt')`), and it is not stable across loads. A\n// content component that saw it would embed it in hrefs and keys. So the corpus scope\n// rebases every path it hands out to the corpus root (`/roadmap/x.mdx`), which is the same\n// address under fork, library and dispatch composition — `PLATFORM_LAYERING_SPEC` §1.1's\n// mode-invariance rule, applied to metadata rather than to links.\n//\n// **Why the href mapping is injected rather than derived.** Corpus path → in-app URL is\n// VIEWER policy, and the two packagings genuinely disagree (a fork's URLs are anchored at\n// its app root and are already published and cited; a dispatched viewer's are corpus-\n// relative). A content component must not have to know which it is in, and the SDK must\n// not guess — so the viewer supplies `toHref` and content never computes a URL itself.\n\nimport { createContext, use, useMemo } from 'react';\nimport { useMetadataStore } from './metadataSource';\nimport type { Metadata } from './sandboxTypes';\n\n/** What a corpus viewer declares about the corpus it is rendering. */\nexport interface CorpusScope {\n /**\n * Absolute filesystem path of the corpus root, WITHOUT a trailing slash\n * (`/app/content` in a fork, `/mnt/<hash>` under dispatch), or `null` when the\n * surrounding app is not rendering a corpus — the default, which leaves every hook here\n * returning the empty result rather than guessing a root.\n */\n root: string | null;\n /** Corpus-absolute path of the entry currently being read (`/roadmap/R3-174.mdx`), or\n * `null` when nothing is. This is the entry, NOT the file being rendered: a component\n * in a `_layout.mdx` wrapping that entry sees the entry, which is what makes furniture\n * in the layout chain (a status line, a dependency rail) able to describe the page. */\n entry: string | null;\n /** Corpus-absolute path → the href to navigate to it. Supplied by the viewer; the\n * identity function by default, which is correct for a viewer whose URL space IS the\n * corpus space. */\n toHref: (corpusPath: string) => string;\n}\n\nconst EMPTY_SCOPE: CorpusScope = { root: null, entry: null, toHref: (p) => p };\n\n/** Ambient corpus scope. A corpus-rendering app wraps its content tree in\n * `<CorpusContext value={{ root, entry, toHref }}>`; nesting a second provider inside a\n * rendered sub-corpus makes the innermost win, as with {@link LinkSpaceContext}. */\nexport const CorpusContext = createContext<CorpusScope>(EMPTY_SCOPE);\n\n/** Read the ambient corpus scope. Every hook below is a convenience over this. */\nexport const useCorpus = (): CorpusScope => use(CorpusContext);\n\n/**\n * Filesystem-absolute path → corpus-absolute, or `null` when the path is not inside the\n * corpus. Exact-root and separator-boundary aware, so `/mnt/hash2/x` is not treated as\n * living under `/mnt/hash`.\n */\nexport const toCorpusPath = (absolute: string, root: string | null): string | null => {\n if (root === null) return null;\n const base = root.replace(/\\/+$/, '');\n if (base === '') return absolute;\n if (!absolute.startsWith(`${base}/`)) return null;\n return absolute.slice(base.length);\n};\n\n/** Corpus-absolute path → filesystem-absolute, or `null` without a root. The inverse of\n * {@link toCorpusPath}, for the rare content component that must read raw bytes. */\nexport const fromCorpusPath = (corpusPath: string, root: string | null): string | null => {\n if (root === null) return null;\n const base = root.replace(/\\/+$/, '');\n return `${base}${corpusPath.startsWith('/') ? '' : '/'}${corpusPath}`;\n};\n\n/** One entry as content sees it: where it is, where it links, and its frontmatter. */\nexport interface CorpusEntry<T = Metadata> {\n /** Corpus-absolute path (`/roadmap/R3-174.mdx`). */\n path: string;\n /** The href that navigates to it, per the viewer's mapping. */\n href: string;\n meta: T;\n}\n\n/**\n * Every entry in the surrounding corpus, with corpus-absolute paths and viewer-supplied\n * hrefs — the surface a content component queries instead of {@link useMetadataQuery},\n * whose keys are filesystem-absolute and therefore carry the mount prefix.\n *\n * Returns an empty array outside a corpus, so a component written for a corpus renders\n * nothing rather than throwing when someone drops it elsewhere. The array keeps its\n * identity while the store and root are unchanged, so it is safe in dependency arrays.\n */\nexport const useCorpusEntries = <T = Metadata>(): CorpusEntry<T>[] => {\n const files = useMetadataStore<T>();\n const { root, toHref } = useCorpus();\n return useMemo(() => {\n if (root === null) return [];\n const out: CorpusEntry<T>[] = [];\n for (const [absolute, meta] of Object.entries(files)) {\n const path = toCorpusPath(absolute, root);\n if (path === null) continue;\n out.push({ path, href: toHref(path), meta: meta as T });\n }\n // Path order, so a consumer that does not sort still renders deterministically\n // (object key order is insertion order, which is scan order, which is not stable).\n out.sort((a, b) => a.path.localeCompare(b.path));\n return out;\n }, [files, root, toHref]);\n};\n\n/** One entry's frontmatter by corpus-absolute path, or `undefined`. */\nexport const useCorpusEntry = <T = Metadata>(corpusPath: string): T | undefined => {\n const files = useMetadataStore<T>();\n const { root } = useCorpus();\n return useMemo(() => {\n const absolute = fromCorpusPath(corpusPath, root);\n return absolute === null ? undefined : files[absolute];\n }, [corpusPath, files, root]);\n};\n\n/** The entry currently being read — `null` outside a corpus, or when the viewer declares\n * no entry (a directory listing, a 404). See {@link CorpusScope.entry} for why this is\n * the entry rather than the file the component happens to be written in. */\nexport const useCurrentEntry = <T = Metadata>(): CorpusEntry<T> | null => {\n const files = useMetadataStore<T>();\n const { root, entry, toHref } = useCorpus();\n return useMemo(() => {\n if (root === null || entry === null) return null;\n const absolute = fromCorpusPath(entry, root);\n const meta = absolute === null ? undefined : files[absolute];\n if (meta === undefined) return null;\n return { path: entry, href: toHref(entry), meta: meta as T };\n }, [files, root, entry, toHref]);\n};\n"],"mappings":";AA4BA,SAAS,eAAe,KAAK,eAAe;AAC5C,SAAS,wBAAwB;AAuBjC,MAAM,cAA2B,EAAE,MAAM,MAAM,OAAO,MAAM,QAAQ,CAAC,MAAM,EAAE;AAKtE,MAAM,gBAAgB,cAA2B,WAAW;AAG5D,MAAM,YAAY,MAAmB,IAAI,aAAa;AAOtD,MAAM,eAAe,CAAC,UAAkB,SAAuC;AACpF,MAAI,SAAS,KAAM,QAAO;AAC1B,QAAM,OAAO,KAAK,QAAQ,QAAQ,EAAE;AACpC,MAAI,SAAS,GAAI,QAAO;AACxB,MAAI,CAAC,SAAS,WAAW,GAAG,IAAI,GAAG,EAAG,QAAO;AAC7C,SAAO,SAAS,MAAM,KAAK,MAAM;AACnC;AAIO,MAAM,iBAAiB,CAAC,YAAoB,SAAuC;AACxF,MAAI,SAAS,KAAM,QAAO;AAC1B,QAAM,OAAO,KAAK,QAAQ,QAAQ,EAAE;AACpC,SAAO,GAAG,IAAI,GAAG,WAAW,WAAW,GAAG,IAAI,KAAK,GAAG,GAAG,UAAU;AACrE;AAoBO,MAAM,mBAAmB,MAAsC;AACpE,QAAM,QAAQ,iBAAoB;AAClC,QAAM,EAAE,MAAM,OAAO,IAAI,UAAU;AACnC,SAAO,QAAQ,MAAM;AACnB,QAAI,SAAS,KAAM,QAAO,CAAC;AAC3B,UAAM,MAAwB,CAAC;AAC/B,eAAW,CAAC,UAAU,IAAI,KAAK,OAAO,QAAQ,KAAK,GAAG;AACpD,YAAM,OAAO,aAAa,UAAU,IAAI;AACxC,UAAI,SAAS,KAAM;AACnB,UAAI,KAAK,EAAE,MAAM,MAAM,OAAO,IAAI,GAAG,KAAgB,CAAC;AAAA,IACxD;AAGA,QAAI,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AAC/C,WAAO;AAAA,EACT,GAAG,CAAC,OAAO,MAAM,MAAM,CAAC;AAC1B;AAGO,MAAM,iBAAiB,CAAe,eAAsC;AACjF,QAAM,QAAQ,iBAAoB;AAClC,QAAM,EAAE,KAAK,IAAI,UAAU;AAC3B,SAAO,QAAQ,MAAM;AACnB,UAAM,WAAW,eAAe,YAAY,IAAI;AAChD,WAAO,aAAa,OAAO,SAAY,MAAM,QAAQ;AAAA,EACvD,GAAG,CAAC,YAAY,OAAO,IAAI,CAAC;AAC9B;AAKO,MAAM,kBAAkB,MAA2C;AACxE,QAAM,QAAQ,iBAAoB;AAClC,QAAM,EAAE,MAAM,OAAO,OAAO,IAAI,UAAU;AAC1C,SAAO,QAAQ,MAAM;AACnB,QAAI,SAAS,QAAQ,UAAU,KAAM,QAAO;AAC5C,UAAM,WAAW,eAAe,OAAO,IAAI;AAC3C,UAAM,OAAO,aAAa,OAAO,SAAY,MAAM,QAAQ;AAC3D,QAAI,SAAS,OAAW,QAAO;AAC/B,WAAO,EAAE,MAAM,OAAO,MAAM,OAAO,KAAK,GAAG,KAAgB;AAAA,EAC7D,GAAG,CAAC,OAAO,MAAM,OAAO,MAAM,CAAC;AACjC;","names":[]}
|
package/dist/index.cjs
CHANGED
|
@@ -32,6 +32,7 @@ var import_SafeInclude = require("./components/SafeInclude");
|
|
|
32
32
|
__reExport(index_exports, require("./sourceCache"), module.exports);
|
|
33
33
|
__reExport(index_exports, require("./components/MDXComponents"), module.exports);
|
|
34
34
|
__reExport(index_exports, require("./linkSpace"), module.exports);
|
|
35
|
+
__reExport(index_exports, require("./corpus"), module.exports);
|
|
35
36
|
__reExport(index_exports, require("./components/MountImage"), module.exports);
|
|
36
37
|
__reExport(index_exports, require("./components/Routes"), module.exports);
|
|
37
38
|
__reExport(index_exports, require("./hooks"), module.exports);
|
|
@@ -45,6 +46,7 @@ __reExport(index_exports, require("./formFactor"), module.exports);
|
|
|
45
46
|
__reExport(index_exports, require("./hostAttention"), module.exports);
|
|
46
47
|
__reExport(index_exports, require("./region"), module.exports);
|
|
47
48
|
__reExport(index_exports, require("./mounts"), module.exports);
|
|
49
|
+
__reExport(index_exports, require("./analytics"), module.exports);
|
|
48
50
|
__reExport(index_exports, require("./contribute"), module.exports);
|
|
49
51
|
__reExport(index_exports, require("./catalog"), module.exports);
|
|
50
52
|
__reExport(index_exports, require("./ipc"), module.exports);
|
|
@@ -79,6 +81,7 @@ __reExport(index_exports, require("./safeContent"), module.exports);
|
|
|
79
81
|
...require("./sourceCache"),
|
|
80
82
|
...require("./components/MDXComponents"),
|
|
81
83
|
...require("./linkSpace"),
|
|
84
|
+
...require("./corpus"),
|
|
82
85
|
...require("./components/MountImage"),
|
|
83
86
|
...require("./components/Routes"),
|
|
84
87
|
...require("./hooks"),
|
|
@@ -91,6 +94,7 @@ __reExport(index_exports, require("./safeContent"), module.exports);
|
|
|
91
94
|
...require("./hostAttention"),
|
|
92
95
|
...require("./region"),
|
|
93
96
|
...require("./mounts"),
|
|
97
|
+
...require("./analytics"),
|
|
94
98
|
...require("./contribute"),
|
|
95
99
|
...require("./catalog"),
|
|
96
100
|
...require("./ipc"),
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from './MDXProvider';\nexport * from './routing';\nexport * from './boot';\nexport * from './components/Include';\n// Only the component is public. `stripFrontmatter`/`appMountRelative` are module-level\n// exports so they can be unit-tested directly, NOT public API — the SDK's surface is\n// backwards-compatible forever, so an internal helper exported for a test's convenience is a\n// permanent commitment made for the wrong reason.\nexport { SafeInclude } from './components/SafeInclude';\nexport * from './sourceCache';\nexport * from './components/MDXComponents';\nexport * from './linkSpace';\nexport * from './components/MountImage';\nexport * from './components/Routes';\nexport * from './hooks';\n// R3-276: the supported way for a viewer app to provide its own metadata store,\n// replacing a wholesale re-provision of `TinkerableContext` in app code.\nexport * from './metadataSource';\n// The deprecated injected-bundler adapters, re-exported so their deprecation notices\n// are visible in the published docs (R3-278; the window only narrows).\nexport { getInjectedMetadataEmitter, getInjectedMetadataSnapshot } from './injectedBundler';\nexport * from './auth';\nexport * from './theme';\nexport * from './editorContext';\nexport * from './editor';\nexport * from './formFactor';\nexport * from './hostAttention';\nexport * from './region';\nexport * from './mounts';\nexport * from './contribute';\nexport * from './catalog';\nexport * from './ipc';\nexport * from './dnd';\nexport * from './netFetch';\nexport * from './secrets';\nexport * from './llm';\nexport * from './diagnostics';\nexport * from './vcs';\nexport * from './onFsChange';\nexport * from './fs';\nexport * from './debug';\nexport * from './tasks';\nexport * from './launch';\nexport * from './runtime';\nexport * from './irMarkers';\nexport * from './ready';\nexport * from './loading';\nexport * from './protocolStream';\nexport * from './protocolDeadline';\nexport * from './sandboxTypes';\nexport * from './safeContent';\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAAc,0BAAd;AACA,0BAAc,sBADd;AAEA,0BAAc,mBAFd;AAGA,0BAAc,iCAHd;AAQA,yBAA4B;AAC5B,0BAAc,0BATd;AAUA,0BAAc,uCAVd;AAWA,0BAAc,wBAXd;AAYA,0BAAc,
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from './MDXProvider';\nexport * from './routing';\nexport * from './boot';\nexport * from './components/Include';\n// Only the component is public. `stripFrontmatter`/`appMountRelative` are module-level\n// exports so they can be unit-tested directly, NOT public API — the SDK's surface is\n// backwards-compatible forever, so an internal helper exported for a test's convenience is a\n// permanent commitment made for the wrong reason.\nexport { SafeInclude } from './components/SafeInclude';\nexport * from './sourceCache';\nexport * from './components/MDXComponents';\nexport * from './linkSpace';\nexport * from './corpus';\nexport * from './components/MountImage';\nexport * from './components/Routes';\nexport * from './hooks';\n// R3-276: the supported way for a viewer app to provide its own metadata store,\n// replacing a wholesale re-provision of `TinkerableContext` in app code.\nexport * from './metadataSource';\n// The deprecated injected-bundler adapters, re-exported so their deprecation notices\n// are visible in the published docs (R3-278; the window only narrows).\nexport { getInjectedMetadataEmitter, getInjectedMetadataSnapshot } from './injectedBundler';\nexport * from './auth';\nexport * from './theme';\nexport * from './editorContext';\nexport * from './editor';\nexport * from './formFactor';\nexport * from './hostAttention';\nexport * from './region';\nexport * from './mounts';\nexport * from './analytics';\nexport * from './contribute';\nexport * from './catalog';\nexport * from './ipc';\nexport * from './dnd';\nexport * from './netFetch';\nexport * from './secrets';\nexport * from './llm';\nexport * from './diagnostics';\nexport * from './vcs';\nexport * from './onFsChange';\nexport * from './fs';\nexport * from './debug';\nexport * from './tasks';\nexport * from './launch';\nexport * from './runtime';\nexport * from './irMarkers';\nexport * from './ready';\nexport * from './loading';\nexport * from './protocolStream';\nexport * from './protocolDeadline';\nexport * from './sandboxTypes';\nexport * from './safeContent';\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAAc,0BAAd;AACA,0BAAc,sBADd;AAEA,0BAAc,mBAFd;AAGA,0BAAc,iCAHd;AAQA,yBAA4B;AAC5B,0BAAc,0BATd;AAUA,0BAAc,uCAVd;AAWA,0BAAc,wBAXd;AAYA,0BAAc,qBAZd;AAaA,0BAAc,oCAbd;AAcA,0BAAc,gCAdd;AAeA,0BAAc,oBAfd;AAkBA,0BAAc,6BAlBd;AAqBA,6BAAwE;AACxE,0BAAc,mBAtBd;AAuBA,0BAAc,oBAvBd;AAwBA,0BAAc,4BAxBd;AAyBA,0BAAc,qBAzBd;AA0BA,0BAAc,yBA1Bd;AA2BA,0BAAc,4BA3Bd;AA4BA,0BAAc,qBA5Bd;AA6BA,0BAAc,qBA7Bd;AA8BA,0BAAc,wBA9Bd;AA+BA,0BAAc,yBA/Bd;AAgCA,0BAAc,sBAhCd;AAiCA,0BAAc,kBAjCd;AAkCA,0BAAc,kBAlCd;AAmCA,0BAAc,uBAnCd;AAoCA,0BAAc,sBApCd;AAqCA,0BAAc,kBArCd;AAsCA,0BAAc,0BAtCd;AAuCA,0BAAc,kBAvCd;AAwCA,0BAAc,yBAxCd;AAyCA,0BAAc,iBAzCd;AA0CA,0BAAc,oBA1Cd;AA2CA,0BAAc,oBA3Cd;AA4CA,0BAAc,qBA5Cd;AA6CA,0BAAc,sBA7Cd;AA8CA,0BAAc,wBA9Cd;AA+CA,0BAAc,oBA/Cd;AAgDA,0BAAc,sBAhDd;AAiDA,0BAAc,6BAjDd;AAkDA,0BAAc,+BAlDd;AAmDA,0BAAc,2BAnDd;AAoDA,0BAAc,0BApDd;","names":[]}
|
package/dist/index.d.cts
CHANGED
|
@@ -6,6 +6,7 @@ export { SafeInclude } from './components/SafeInclude.cjs';
|
|
|
6
6
|
export { SourceCache, SourceReader, createSourceCache } from './sourceCache.cjs';
|
|
7
7
|
export { DEFAULT_MDX_COMPONENTS } from './components/MDXComponents.cjs';
|
|
8
8
|
export { LinkSpaceContext } from './linkSpace.cjs';
|
|
9
|
+
export { CorpusContext, CorpusEntry, CorpusScope, fromCorpusPath, toCorpusPath, useCorpus, useCorpusEntries, useCorpusEntry, useCurrentEntry } from './corpus.cjs';
|
|
9
10
|
export { MountImage, MountImageProps } from './components/MountImage.cjs';
|
|
10
11
|
export { Route, RouteProps, Routes } from './components/Routes.cjs';
|
|
11
12
|
export { ObjectUrlState, useAllMetadata, useFileMetadata, useMetadataQuery, useObjectUrl } from './hooks.cjs';
|
|
@@ -19,6 +20,7 @@ export { FormFactor, FormFactorClass, Orientation, getFormFactor, onFormFactorCh
|
|
|
19
20
|
export { HostAttention, HostAttentionKind, NO_HOST_ATTENTION, getHostAttention, onHostAttentionChange, useHostAttention } from './hostAttention.cjs';
|
|
20
21
|
export { getRegion, useRegion } from './region.cjs';
|
|
21
22
|
export { Invite, MountQuery, MountRemoveReason, MountRule, RemovedMount, SandboxMount, SessionMount, SpaceError, acceptInvite, awaitMatchingMount, createSpace, declineInvite, findMount, getAppMountPath, getInvites, getMounts, getSessionMounts, importSettingsFromParent, listMyInvites, listPendingInvites, listSettingsApps, makeContentRef, mount, mountSpace, onInvitesChange, onMountsChange, onSessionMountsChange, openSettings, openSettingsOf, requestMount, requestSpace, resolveContentRef, resolveContentRefs, revokeInvite, unmountSpace, useInvites, useMounts, useSessionMounts, waitForMount } from './mounts.cjs';
|
|
23
|
+
export { AnalyticsAck, AnalyticsPropValue, emitAnalyticsEvent, recordRoute, track, trackRoute } from './analytics.cjs';
|
|
22
24
|
export { ContributeMode, ContributeOptions, ContributionEvent, ContributionResult, contribute } from './contribute.cjs';
|
|
23
25
|
export { ApiMethod, getCatalog, invoke, invokeStream, onCatalogChange, useCatalog } from './catalog.cjs';
|
|
24
26
|
export { RegionMessage, onRegionMessage, postToRegion, revealRegion, useRegionMessage } from './ipc.cjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,7 @@ export { SafeInclude } from './components/SafeInclude.js';
|
|
|
6
6
|
export { SourceCache, SourceReader, createSourceCache } from './sourceCache.js';
|
|
7
7
|
export { DEFAULT_MDX_COMPONENTS } from './components/MDXComponents.js';
|
|
8
8
|
export { LinkSpaceContext } from './linkSpace.js';
|
|
9
|
+
export { CorpusContext, CorpusEntry, CorpusScope, fromCorpusPath, toCorpusPath, useCorpus, useCorpusEntries, useCorpusEntry, useCurrentEntry } from './corpus.js';
|
|
9
10
|
export { MountImage, MountImageProps } from './components/MountImage.js';
|
|
10
11
|
export { Route, RouteProps, Routes } from './components/Routes.js';
|
|
11
12
|
export { ObjectUrlState, useAllMetadata, useFileMetadata, useMetadataQuery, useObjectUrl } from './hooks.js';
|
|
@@ -19,6 +20,7 @@ export { FormFactor, FormFactorClass, Orientation, getFormFactor, onFormFactorCh
|
|
|
19
20
|
export { HostAttention, HostAttentionKind, NO_HOST_ATTENTION, getHostAttention, onHostAttentionChange, useHostAttention } from './hostAttention.js';
|
|
20
21
|
export { getRegion, useRegion } from './region.js';
|
|
21
22
|
export { Invite, MountQuery, MountRemoveReason, MountRule, RemovedMount, SandboxMount, SessionMount, SpaceError, acceptInvite, awaitMatchingMount, createSpace, declineInvite, findMount, getAppMountPath, getInvites, getMounts, getSessionMounts, importSettingsFromParent, listMyInvites, listPendingInvites, listSettingsApps, makeContentRef, mount, mountSpace, onInvitesChange, onMountsChange, onSessionMountsChange, openSettings, openSettingsOf, requestMount, requestSpace, resolveContentRef, resolveContentRefs, revokeInvite, unmountSpace, useInvites, useMounts, useSessionMounts, waitForMount } from './mounts.js';
|
|
23
|
+
export { AnalyticsAck, AnalyticsPropValue, emitAnalyticsEvent, recordRoute, track, trackRoute } from './analytics.js';
|
|
22
24
|
export { ContributeMode, ContributeOptions, ContributionEvent, ContributionResult, contribute } from './contribute.js';
|
|
23
25
|
export { ApiMethod, getCatalog, invoke, invokeStream, onCatalogChange, useCatalog } from './catalog.js';
|
|
24
26
|
export { RegionMessage, onRegionMessage, postToRegion, revealRegion, useRegionMessage } from './ipc.js';
|
package/dist/index.js
CHANGED
|
@@ -7,6 +7,7 @@ import { SafeInclude } from "./components/SafeInclude";
|
|
|
7
7
|
export * from "./sourceCache";
|
|
8
8
|
export * from "./components/MDXComponents";
|
|
9
9
|
export * from "./linkSpace";
|
|
10
|
+
export * from "./corpus";
|
|
10
11
|
export * from "./components/MountImage";
|
|
11
12
|
export * from "./components/Routes";
|
|
12
13
|
export * from "./hooks";
|
|
@@ -20,6 +21,7 @@ export * from "./formFactor";
|
|
|
20
21
|
export * from "./hostAttention";
|
|
21
22
|
export * from "./region";
|
|
22
23
|
export * from "./mounts";
|
|
24
|
+
export * from "./analytics";
|
|
23
25
|
export * from "./contribute";
|
|
24
26
|
export * from "./catalog";
|
|
25
27
|
export * from "./ipc";
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from './MDXProvider';\nexport * from './routing';\nexport * from './boot';\nexport * from './components/Include';\n// Only the component is public. `stripFrontmatter`/`appMountRelative` are module-level\n// exports so they can be unit-tested directly, NOT public API — the SDK's surface is\n// backwards-compatible forever, so an internal helper exported for a test's convenience is a\n// permanent commitment made for the wrong reason.\nexport { SafeInclude } from './components/SafeInclude';\nexport * from './sourceCache';\nexport * from './components/MDXComponents';\nexport * from './linkSpace';\nexport * from './components/MountImage';\nexport * from './components/Routes';\nexport * from './hooks';\n// R3-276: the supported way for a viewer app to provide its own metadata store,\n// replacing a wholesale re-provision of `TinkerableContext` in app code.\nexport * from './metadataSource';\n// The deprecated injected-bundler adapters, re-exported so their deprecation notices\n// are visible in the published docs (R3-278; the window only narrows).\nexport { getInjectedMetadataEmitter, getInjectedMetadataSnapshot } from './injectedBundler';\nexport * from './auth';\nexport * from './theme';\nexport * from './editorContext';\nexport * from './editor';\nexport * from './formFactor';\nexport * from './hostAttention';\nexport * from './region';\nexport * from './mounts';\nexport * from './contribute';\nexport * from './catalog';\nexport * from './ipc';\nexport * from './dnd';\nexport * from './netFetch';\nexport * from './secrets';\nexport * from './llm';\nexport * from './diagnostics';\nexport * from './vcs';\nexport * from './onFsChange';\nexport * from './fs';\nexport * from './debug';\nexport * from './tasks';\nexport * from './launch';\nexport * from './runtime';\nexport * from './irMarkers';\nexport * from './ready';\nexport * from './loading';\nexport * from './protocolStream';\nexport * from './protocolDeadline';\nexport * from './sandboxTypes';\nexport * from './safeContent';\n"],"mappings":";AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AAKd,SAAS,mBAAmB;AAC5B,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AAGd,cAAc;AAGd,SAAS,4BAA4B,mCAAmC;AACxE,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from './MDXProvider';\nexport * from './routing';\nexport * from './boot';\nexport * from './components/Include';\n// Only the component is public. `stripFrontmatter`/`appMountRelative` are module-level\n// exports so they can be unit-tested directly, NOT public API — the SDK's surface is\n// backwards-compatible forever, so an internal helper exported for a test's convenience is a\n// permanent commitment made for the wrong reason.\nexport { SafeInclude } from './components/SafeInclude';\nexport * from './sourceCache';\nexport * from './components/MDXComponents';\nexport * from './linkSpace';\nexport * from './corpus';\nexport * from './components/MountImage';\nexport * from './components/Routes';\nexport * from './hooks';\n// R3-276: the supported way for a viewer app to provide its own metadata store,\n// replacing a wholesale re-provision of `TinkerableContext` in app code.\nexport * from './metadataSource';\n// The deprecated injected-bundler adapters, re-exported so their deprecation notices\n// are visible in the published docs (R3-278; the window only narrows).\nexport { getInjectedMetadataEmitter, getInjectedMetadataSnapshot } from './injectedBundler';\nexport * from './auth';\nexport * from './theme';\nexport * from './editorContext';\nexport * from './editor';\nexport * from './formFactor';\nexport * from './hostAttention';\nexport * from './region';\nexport * from './mounts';\nexport * from './analytics';\nexport * from './contribute';\nexport * from './catalog';\nexport * from './ipc';\nexport * from './dnd';\nexport * from './netFetch';\nexport * from './secrets';\nexport * from './llm';\nexport * from './diagnostics';\nexport * from './vcs';\nexport * from './onFsChange';\nexport * from './fs';\nexport * from './debug';\nexport * from './tasks';\nexport * from './launch';\nexport * from './runtime';\nexport * from './irMarkers';\nexport * from './ready';\nexport * from './loading';\nexport * from './protocolStream';\nexport * from './protocolDeadline';\nexport * from './sandboxTypes';\nexport * from './safeContent';\n"],"mappings":";AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AAKd,SAAS,mBAAmB;AAC5B,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AAGd,cAAc;AAGd,SAAS,4BAA4B,mCAAmC;AACxE,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
|
package/dist/protocolSchemes.cjs
CHANGED
|
@@ -25,6 +25,7 @@ var import_protocol = require("./generated/protocol");
|
|
|
25
25
|
const PREFIX = "protocol-";
|
|
26
26
|
const schemeOf = (name) => name.slice(PREFIX.length);
|
|
27
27
|
const SCHEMES = {
|
|
28
|
+
[import_protocol.PROTOCOL_ANALYTICS]: schemeOf(import_protocol.PROTOCOL_ANALYTICS),
|
|
28
29
|
[import_protocol.PROTOCOL_CONTRIBUTE]: schemeOf(import_protocol.PROTOCOL_CONTRIBUTE),
|
|
29
30
|
[import_protocol.PROTOCOL_DND]: schemeOf(import_protocol.PROTOCOL_DND),
|
|
30
31
|
[import_protocol.PROTOCOL_EDITOR]: schemeOf(import_protocol.PROTOCOL_EDITOR),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/protocolSchemes.ts"],"sourcesContent":["// The `protocol-<scheme>` SCHEMES, derived from the wire names.\n//\n// `protocolRequest(scheme, method, params)` takes the scheme — `'theme'` — while the\n// wire name the frame dispatches on is `'protocol-theme'`; the frame adds the prefix.\n// So the typed service wrappers cannot pass the published `PROTOCOL_*` constant\n// directly, and spelling the scheme inline would put a second, unguarded copy of the\n// name back in the tree — exactly what R3-274c removes.\n//\n// Instead the schemes are *derived* from the wire names, keyed BY the wire name:\n//\n// protocolRequest(SCHEMES[PROTOCOL_THEME], 'set', [{ theme }])\n//\n// Keying by the constant is what makes the derivation unfalsifiable — there is no\n// second place to name the family, so there is no pair to get wrong. `schemeOf`\n// returns a template-literal conditional, so each value has a literal type (`'theme'`),\n// which buys two more things:\n//\n// - a wire name that stops matching `protocol-*` stops compiling here, rather than\n// silently producing an empty scheme at runtime;\n// - `check-protocol-snapshot.mjs` resolves `SCHEMES[PROTOCOL_THEME]` through the type\n// checker exactly like a plain literal, so the call sites stay visible to the gate.\n//\n// One export, deliberately: `./*` is a public subpath, so every name added here is\n// public API forever (ways_of_working §6, additive-only).\n//\n// This module is NOT generated — the derivation is the content — so it lives outside\n// `src/generated/`.\nimport {\n PROTOCOL_CONTRIBUTE,\n PROTOCOL_DND,\n PROTOCOL_EDITOR,\n PROTOCOL_FETCH,\n PROTOCOL_IPC,\n PROTOCOL_LAUNCH,\n PROTOCOL_LLM,\n PROTOCOL_SECRETS,\n PROTOCOL_SETTINGS,\n PROTOCOL_SPACES,\n PROTOCOL_TASK,\n PROTOCOL_THEME,\n PROTOCOL_VCS,\n} from './generated/protocol';\n\nconst PREFIX = 'protocol-';\n\n/** The scheme half of a `protocol-<scheme>` wire name. */\ntype SchemeOf<N extends string> = N extends `${typeof PREFIX}${infer S}` ? S : never;\n\n/**\n * `'protocol-theme'` → `'theme'`, as a literal type.\n *\n * The cast is the only place the derivation is asserted rather than computed; the\n * `N extends \\`protocol-${string}\\`` bound is what makes it sound — a wire name that is\n * not scheme-shaped is a compile error at the call, not a `never` at runtime.\n */\nconst schemeOf = <N extends `${typeof PREFIX}${string}`>(name: N): SchemeOf<N> =>\n name.slice(PREFIX.length) as SchemeOf<N>;\n\n/** Every `protocol-*` scheme the SDK speaks, keyed by its wire name. */\nexport const SCHEMES = {\n [PROTOCOL_CONTRIBUTE]: schemeOf(PROTOCOL_CONTRIBUTE),\n [PROTOCOL_DND]: schemeOf(PROTOCOL_DND),\n [PROTOCOL_EDITOR]: schemeOf(PROTOCOL_EDITOR),\n [PROTOCOL_FETCH]: schemeOf(PROTOCOL_FETCH),\n [PROTOCOL_IPC]: schemeOf(PROTOCOL_IPC),\n [PROTOCOL_LAUNCH]: schemeOf(PROTOCOL_LAUNCH),\n [PROTOCOL_LLM]: schemeOf(PROTOCOL_LLM),\n [PROTOCOL_SECRETS]: schemeOf(PROTOCOL_SECRETS),\n [PROTOCOL_SETTINGS]: schemeOf(PROTOCOL_SETTINGS),\n [PROTOCOL_SPACES]: schemeOf(PROTOCOL_SPACES),\n [PROTOCOL_TASK]: schemeOf(PROTOCOL_TASK),\n [PROTOCOL_THEME]: schemeOf(PROTOCOL_THEME),\n [PROTOCOL_VCS]: schemeOf(PROTOCOL_VCS),\n} as const;\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA2BA,
|
|
1
|
+
{"version":3,"sources":["../src/protocolSchemes.ts"],"sourcesContent":["// The `protocol-<scheme>` SCHEMES, derived from the wire names.\n//\n// `protocolRequest(scheme, method, params)` takes the scheme — `'theme'` — while the\n// wire name the frame dispatches on is `'protocol-theme'`; the frame adds the prefix.\n// So the typed service wrappers cannot pass the published `PROTOCOL_*` constant\n// directly, and spelling the scheme inline would put a second, unguarded copy of the\n// name back in the tree — exactly what R3-274c removes.\n//\n// Instead the schemes are *derived* from the wire names, keyed BY the wire name:\n//\n// protocolRequest(SCHEMES[PROTOCOL_THEME], 'set', [{ theme }])\n//\n// Keying by the constant is what makes the derivation unfalsifiable — there is no\n// second place to name the family, so there is no pair to get wrong. `schemeOf`\n// returns a template-literal conditional, so each value has a literal type (`'theme'`),\n// which buys two more things:\n//\n// - a wire name that stops matching `protocol-*` stops compiling here, rather than\n// silently producing an empty scheme at runtime;\n// - `check-protocol-snapshot.mjs` resolves `SCHEMES[PROTOCOL_THEME]` through the type\n// checker exactly like a plain literal, so the call sites stay visible to the gate.\n//\n// One export, deliberately: `./*` is a public subpath, so every name added here is\n// public API forever (ways_of_working §6, additive-only).\n//\n// This module is NOT generated — the derivation is the content — so it lives outside\n// `src/generated/`.\nimport {\n PROTOCOL_ANALYTICS,\n PROTOCOL_CONTRIBUTE,\n PROTOCOL_DND,\n PROTOCOL_EDITOR,\n PROTOCOL_FETCH,\n PROTOCOL_IPC,\n PROTOCOL_LAUNCH,\n PROTOCOL_LLM,\n PROTOCOL_SECRETS,\n PROTOCOL_SETTINGS,\n PROTOCOL_SPACES,\n PROTOCOL_TASK,\n PROTOCOL_THEME,\n PROTOCOL_VCS,\n} from './generated/protocol';\n\nconst PREFIX = 'protocol-';\n\n/** The scheme half of a `protocol-<scheme>` wire name. */\ntype SchemeOf<N extends string> = N extends `${typeof PREFIX}${infer S}` ? S : never;\n\n/**\n * `'protocol-theme'` → `'theme'`, as a literal type.\n *\n * The cast is the only place the derivation is asserted rather than computed; the\n * `N extends \\`protocol-${string}\\`` bound is what makes it sound — a wire name that is\n * not scheme-shaped is a compile error at the call, not a `never` at runtime.\n */\nconst schemeOf = <N extends `${typeof PREFIX}${string}`>(name: N): SchemeOf<N> =>\n name.slice(PREFIX.length) as SchemeOf<N>;\n\n/** Every `protocol-*` scheme the SDK speaks, keyed by its wire name. */\nexport const SCHEMES = {\n [PROTOCOL_ANALYTICS]: schemeOf(PROTOCOL_ANALYTICS),\n [PROTOCOL_CONTRIBUTE]: schemeOf(PROTOCOL_CONTRIBUTE),\n [PROTOCOL_DND]: schemeOf(PROTOCOL_DND),\n [PROTOCOL_EDITOR]: schemeOf(PROTOCOL_EDITOR),\n [PROTOCOL_FETCH]: schemeOf(PROTOCOL_FETCH),\n [PROTOCOL_IPC]: schemeOf(PROTOCOL_IPC),\n [PROTOCOL_LAUNCH]: schemeOf(PROTOCOL_LAUNCH),\n [PROTOCOL_LLM]: schemeOf(PROTOCOL_LLM),\n [PROTOCOL_SECRETS]: schemeOf(PROTOCOL_SECRETS),\n [PROTOCOL_SETTINGS]: schemeOf(PROTOCOL_SETTINGS),\n [PROTOCOL_SPACES]: schemeOf(PROTOCOL_SPACES),\n [PROTOCOL_TASK]: schemeOf(PROTOCOL_TASK),\n [PROTOCOL_THEME]: schemeOf(PROTOCOL_THEME),\n [PROTOCOL_VCS]: schemeOf(PROTOCOL_VCS),\n} as const;\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA2BA,sBAeO;AAEP,MAAM,SAAS;AAYf,MAAM,WAAW,CAAwC,SACvD,KAAK,MAAM,OAAO,MAAM;AAGnB,MAAM,UAAU;AAAA,EACrB,CAAC,kCAAkB,GAAG,SAAS,kCAAkB;AAAA,EACjD,CAAC,mCAAmB,GAAG,SAAS,mCAAmB;AAAA,EACnD,CAAC,4BAAY,GAAG,SAAS,4BAAY;AAAA,EACrC,CAAC,+BAAe,GAAG,SAAS,+BAAe;AAAA,EAC3C,CAAC,8BAAc,GAAG,SAAS,8BAAc;AAAA,EACzC,CAAC,4BAAY,GAAG,SAAS,4BAAY;AAAA,EACrC,CAAC,+BAAe,GAAG,SAAS,+BAAe;AAAA,EAC3C,CAAC,4BAAY,GAAG,SAAS,4BAAY;AAAA,EACrC,CAAC,gCAAgB,GAAG,SAAS,gCAAgB;AAAA,EAC7C,CAAC,iCAAiB,GAAG,SAAS,iCAAiB;AAAA,EAC/C,CAAC,+BAAe,GAAG,SAAS,+BAAe;AAAA,EAC3C,CAAC,6BAAa,GAAG,SAAS,6BAAa;AAAA,EACvC,CAAC,8BAAc,GAAG,SAAS,8BAAc;AAAA,EACzC,CAAC,4BAAY,GAAG,SAAS,4BAAY;AACvC;","names":[]}
|
package/dist/protocolSchemes.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import "./chunk-VHAA22YE.js";
|
|
2
2
|
import {
|
|
3
|
+
PROTOCOL_ANALYTICS,
|
|
3
4
|
PROTOCOL_CONTRIBUTE,
|
|
4
5
|
PROTOCOL_DND,
|
|
5
6
|
PROTOCOL_EDITOR,
|
|
@@ -17,6 +18,7 @@ import {
|
|
|
17
18
|
const PREFIX = "protocol-";
|
|
18
19
|
const schemeOf = (name) => name.slice(PREFIX.length);
|
|
19
20
|
const SCHEMES = {
|
|
21
|
+
[PROTOCOL_ANALYTICS]: schemeOf(PROTOCOL_ANALYTICS),
|
|
20
22
|
[PROTOCOL_CONTRIBUTE]: schemeOf(PROTOCOL_CONTRIBUTE),
|
|
21
23
|
[PROTOCOL_DND]: schemeOf(PROTOCOL_DND),
|
|
22
24
|
[PROTOCOL_EDITOR]: schemeOf(PROTOCOL_EDITOR),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/protocolSchemes.ts"],"sourcesContent":["// The `protocol-<scheme>` SCHEMES, derived from the wire names.\n//\n// `protocolRequest(scheme, method, params)` takes the scheme — `'theme'` — while the\n// wire name the frame dispatches on is `'protocol-theme'`; the frame adds the prefix.\n// So the typed service wrappers cannot pass the published `PROTOCOL_*` constant\n// directly, and spelling the scheme inline would put a second, unguarded copy of the\n// name back in the tree — exactly what R3-274c removes.\n//\n// Instead the schemes are *derived* from the wire names, keyed BY the wire name:\n//\n// protocolRequest(SCHEMES[PROTOCOL_THEME], 'set', [{ theme }])\n//\n// Keying by the constant is what makes the derivation unfalsifiable — there is no\n// second place to name the family, so there is no pair to get wrong. `schemeOf`\n// returns a template-literal conditional, so each value has a literal type (`'theme'`),\n// which buys two more things:\n//\n// - a wire name that stops matching `protocol-*` stops compiling here, rather than\n// silently producing an empty scheme at runtime;\n// - `check-protocol-snapshot.mjs` resolves `SCHEMES[PROTOCOL_THEME]` through the type\n// checker exactly like a plain literal, so the call sites stay visible to the gate.\n//\n// One export, deliberately: `./*` is a public subpath, so every name added here is\n// public API forever (ways_of_working §6, additive-only).\n//\n// This module is NOT generated — the derivation is the content — so it lives outside\n// `src/generated/`.\nimport {\n PROTOCOL_CONTRIBUTE,\n PROTOCOL_DND,\n PROTOCOL_EDITOR,\n PROTOCOL_FETCH,\n PROTOCOL_IPC,\n PROTOCOL_LAUNCH,\n PROTOCOL_LLM,\n PROTOCOL_SECRETS,\n PROTOCOL_SETTINGS,\n PROTOCOL_SPACES,\n PROTOCOL_TASK,\n PROTOCOL_THEME,\n PROTOCOL_VCS,\n} from './generated/protocol';\n\nconst PREFIX = 'protocol-';\n\n/** The scheme half of a `protocol-<scheme>` wire name. */\ntype SchemeOf<N extends string> = N extends `${typeof PREFIX}${infer S}` ? S : never;\n\n/**\n * `'protocol-theme'` → `'theme'`, as a literal type.\n *\n * The cast is the only place the derivation is asserted rather than computed; the\n * `N extends \\`protocol-${string}\\`` bound is what makes it sound — a wire name that is\n * not scheme-shaped is a compile error at the call, not a `never` at runtime.\n */\nconst schemeOf = <N extends `${typeof PREFIX}${string}`>(name: N): SchemeOf<N> =>\n name.slice(PREFIX.length) as SchemeOf<N>;\n\n/** Every `protocol-*` scheme the SDK speaks, keyed by its wire name. */\nexport const SCHEMES = {\n [PROTOCOL_CONTRIBUTE]: schemeOf(PROTOCOL_CONTRIBUTE),\n [PROTOCOL_DND]: schemeOf(PROTOCOL_DND),\n [PROTOCOL_EDITOR]: schemeOf(PROTOCOL_EDITOR),\n [PROTOCOL_FETCH]: schemeOf(PROTOCOL_FETCH),\n [PROTOCOL_IPC]: schemeOf(PROTOCOL_IPC),\n [PROTOCOL_LAUNCH]: schemeOf(PROTOCOL_LAUNCH),\n [PROTOCOL_LLM]: schemeOf(PROTOCOL_LLM),\n [PROTOCOL_SECRETS]: schemeOf(PROTOCOL_SECRETS),\n [PROTOCOL_SETTINGS]: schemeOf(PROTOCOL_SETTINGS),\n [PROTOCOL_SPACES]: schemeOf(PROTOCOL_SPACES),\n [PROTOCOL_TASK]: schemeOf(PROTOCOL_TASK),\n [PROTOCOL_THEME]: schemeOf(PROTOCOL_THEME),\n [PROTOCOL_VCS]: schemeOf(PROTOCOL_VCS),\n} as const;\n"],"mappings":";AA2BA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,MAAM,SAAS;AAYf,MAAM,WAAW,CAAwC,SACvD,KAAK,MAAM,OAAO,MAAM;AAGnB,MAAM,UAAU;AAAA,EACrB,CAAC,mBAAmB,GAAG,SAAS,mBAAmB;AAAA,EACnD,CAAC,YAAY,GAAG,SAAS,YAAY;AAAA,EACrC,CAAC,eAAe,GAAG,SAAS,eAAe;AAAA,EAC3C,CAAC,cAAc,GAAG,SAAS,cAAc;AAAA,EACzC,CAAC,YAAY,GAAG,SAAS,YAAY;AAAA,EACrC,CAAC,eAAe,GAAG,SAAS,eAAe;AAAA,EAC3C,CAAC,YAAY,GAAG,SAAS,YAAY;AAAA,EACrC,CAAC,gBAAgB,GAAG,SAAS,gBAAgB;AAAA,EAC7C,CAAC,iBAAiB,GAAG,SAAS,iBAAiB;AAAA,EAC/C,CAAC,eAAe,GAAG,SAAS,eAAe;AAAA,EAC3C,CAAC,aAAa,GAAG,SAAS,aAAa;AAAA,EACvC,CAAC,cAAc,GAAG,SAAS,cAAc;AAAA,EACzC,CAAC,YAAY,GAAG,SAAS,YAAY;AACvC;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/protocolSchemes.ts"],"sourcesContent":["// The `protocol-<scheme>` SCHEMES, derived from the wire names.\n//\n// `protocolRequest(scheme, method, params)` takes the scheme — `'theme'` — while the\n// wire name the frame dispatches on is `'protocol-theme'`; the frame adds the prefix.\n// So the typed service wrappers cannot pass the published `PROTOCOL_*` constant\n// directly, and spelling the scheme inline would put a second, unguarded copy of the\n// name back in the tree — exactly what R3-274c removes.\n//\n// Instead the schemes are *derived* from the wire names, keyed BY the wire name:\n//\n// protocolRequest(SCHEMES[PROTOCOL_THEME], 'set', [{ theme }])\n//\n// Keying by the constant is what makes the derivation unfalsifiable — there is no\n// second place to name the family, so there is no pair to get wrong. `schemeOf`\n// returns a template-literal conditional, so each value has a literal type (`'theme'`),\n// which buys two more things:\n//\n// - a wire name that stops matching `protocol-*` stops compiling here, rather than\n// silently producing an empty scheme at runtime;\n// - `check-protocol-snapshot.mjs` resolves `SCHEMES[PROTOCOL_THEME]` through the type\n// checker exactly like a plain literal, so the call sites stay visible to the gate.\n//\n// One export, deliberately: `./*` is a public subpath, so every name added here is\n// public API forever (ways_of_working §6, additive-only).\n//\n// This module is NOT generated — the derivation is the content — so it lives outside\n// `src/generated/`.\nimport {\n PROTOCOL_ANALYTICS,\n PROTOCOL_CONTRIBUTE,\n PROTOCOL_DND,\n PROTOCOL_EDITOR,\n PROTOCOL_FETCH,\n PROTOCOL_IPC,\n PROTOCOL_LAUNCH,\n PROTOCOL_LLM,\n PROTOCOL_SECRETS,\n PROTOCOL_SETTINGS,\n PROTOCOL_SPACES,\n PROTOCOL_TASK,\n PROTOCOL_THEME,\n PROTOCOL_VCS,\n} from './generated/protocol';\n\nconst PREFIX = 'protocol-';\n\n/** The scheme half of a `protocol-<scheme>` wire name. */\ntype SchemeOf<N extends string> = N extends `${typeof PREFIX}${infer S}` ? S : never;\n\n/**\n * `'protocol-theme'` → `'theme'`, as a literal type.\n *\n * The cast is the only place the derivation is asserted rather than computed; the\n * `N extends \\`protocol-${string}\\`` bound is what makes it sound — a wire name that is\n * not scheme-shaped is a compile error at the call, not a `never` at runtime.\n */\nconst schemeOf = <N extends `${typeof PREFIX}${string}`>(name: N): SchemeOf<N> =>\n name.slice(PREFIX.length) as SchemeOf<N>;\n\n/** Every `protocol-*` scheme the SDK speaks, keyed by its wire name. */\nexport const SCHEMES = {\n [PROTOCOL_ANALYTICS]: schemeOf(PROTOCOL_ANALYTICS),\n [PROTOCOL_CONTRIBUTE]: schemeOf(PROTOCOL_CONTRIBUTE),\n [PROTOCOL_DND]: schemeOf(PROTOCOL_DND),\n [PROTOCOL_EDITOR]: schemeOf(PROTOCOL_EDITOR),\n [PROTOCOL_FETCH]: schemeOf(PROTOCOL_FETCH),\n [PROTOCOL_IPC]: schemeOf(PROTOCOL_IPC),\n [PROTOCOL_LAUNCH]: schemeOf(PROTOCOL_LAUNCH),\n [PROTOCOL_LLM]: schemeOf(PROTOCOL_LLM),\n [PROTOCOL_SECRETS]: schemeOf(PROTOCOL_SECRETS),\n [PROTOCOL_SETTINGS]: schemeOf(PROTOCOL_SETTINGS),\n [PROTOCOL_SPACES]: schemeOf(PROTOCOL_SPACES),\n [PROTOCOL_TASK]: schemeOf(PROTOCOL_TASK),\n [PROTOCOL_THEME]: schemeOf(PROTOCOL_THEME),\n [PROTOCOL_VCS]: schemeOf(PROTOCOL_VCS),\n} as const;\n"],"mappings":";AA2BA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,MAAM,SAAS;AAYf,MAAM,WAAW,CAAwC,SACvD,KAAK,MAAM,OAAO,MAAM;AAGnB,MAAM,UAAU;AAAA,EACrB,CAAC,kBAAkB,GAAG,SAAS,kBAAkB;AAAA,EACjD,CAAC,mBAAmB,GAAG,SAAS,mBAAmB;AAAA,EACnD,CAAC,YAAY,GAAG,SAAS,YAAY;AAAA,EACrC,CAAC,eAAe,GAAG,SAAS,eAAe;AAAA,EAC3C,CAAC,cAAc,GAAG,SAAS,cAAc;AAAA,EACzC,CAAC,YAAY,GAAG,SAAS,YAAY;AAAA,EACrC,CAAC,eAAe,GAAG,SAAS,eAAe;AAAA,EAC3C,CAAC,YAAY,GAAG,SAAS,YAAY;AAAA,EACrC,CAAC,gBAAgB,GAAG,SAAS,gBAAgB;AAAA,EAC7C,CAAC,iBAAiB,GAAG,SAAS,iBAAiB;AAAA,EAC/C,CAAC,eAAe,GAAG,SAAS,eAAe;AAAA,EAC3C,CAAC,aAAa,GAAG,SAAS,aAAa;AAAA,EACvC,CAAC,cAAc,GAAG,SAAS,cAAc;AAAA,EACzC,CAAC,YAAY,GAAG,SAAS,YAAY;AACvC;","names":[]}
|
package/dist/version.cjs
CHANGED
|
@@ -21,7 +21,7 @@ __export(version_exports, {
|
|
|
21
21
|
SDK_VERSION: () => SDK_VERSION
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(version_exports);
|
|
24
|
-
const SDK_VERSION = "0.
|
|
24
|
+
const SDK_VERSION = "0.52.0";
|
|
25
25
|
// Annotate the CommonJS export names for ESM import in node:
|
|
26
26
|
0 && (module.exports = {
|
|
27
27
|
SDK_VERSION
|
package/dist/version.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/version.ts"],"sourcesContent":["// GENERATED by scripts/gen-version.mjs from package.json — do not edit by hand.\n// Regenerated on every build (prebuild); kept honest by version.test.ts.\n\n/** This SDK's package version, baked from package.json at build (SP2-6). */\nexport const SDK_VERSION = '0.
|
|
1
|
+
{"version":3,"sources":["../src/version.ts"],"sourcesContent":["// GENERATED by scripts/gen-version.mjs from package.json — do not edit by hand.\n// Regenerated on every build (prebuild); kept honest by version.test.ts.\n\n/** This SDK's package version, baked from package.json at build (SP2-6). */\nexport const SDK_VERSION = '0.52.0';\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIO,MAAM,cAAc;","names":[]}
|
package/dist/version.d.cts
CHANGED
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
package/dist/version.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/version.ts"],"sourcesContent":["// GENERATED by scripts/gen-version.mjs from package.json — do not edit by hand.\n// Regenerated on every build (prebuild); kept honest by version.test.ts.\n\n/** This SDK's package version, baked from package.json at build (SP2-6). */\nexport const SDK_VERSION = '0.
|
|
1
|
+
{"version":3,"sources":["../src/version.ts"],"sourcesContent":["// GENERATED by scripts/gen-version.mjs from package.json — do not edit by hand.\n// Regenerated on every build (prebuild); kept honest by version.test.ts.\n\n/** This SDK's package version, baked from package.json at build (SP2-6). */\nexport const SDK_VERSION = '0.52.0';\n"],"mappings":";AAIO,MAAM,cAAc;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@immediately-run/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.52.0",
|
|
4
4
|
"description": "Runtime SDK for code executing inside an immediately.run sandbox.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "github:immediately-run/immediately-run-sdk",
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
60
|
"@immediately-run/platform-constants": "0.2.0",
|
|
61
|
-
"@immediately-run/sandbox-protocol": "0.
|
|
61
|
+
"@immediately-run/sandbox-protocol": "0.5.0",
|
|
62
62
|
"react-error-boundary": "^6.0.0",
|
|
63
63
|
"@immediately-run/safe-content": "0.1.0",
|
|
64
64
|
"@immediately-run/mdx-plugins": "0.5.0"
|