@almadar/shell-runtime 0.1.0 → 1.0.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/chunk-57SBCUSM.js +62 -0
- package/dist/chunk-625EP7W2.js +108 -0
- package/dist/{chunk-NATGCIVM.js → chunk-7WB6VWRK.js} +344 -129
- package/dist/{chunk-Q2H75UYT.js → chunk-A2JJT4GA.js} +1 -37
- package/dist/chunk-BAS26HBN.js +10 -0
- package/dist/{chunk-REPX5QPI.js → chunk-BOVU4TCQ.js} +11 -3
- package/dist/chunk-BY5G4225.js +6 -0
- package/dist/chunk-DFDNHVDW.js +284 -0
- package/dist/chunk-I3TKINSO.js +398 -0
- package/dist/{chunk-DYOJGLIX.js → chunk-LKWYCYX5.js} +2 -5
- package/dist/chunk-LYFIQPXX.js +1 -0
- package/dist/{chunk-VNMG7NKY.js → chunk-MU335ZA4.js} +20 -26
- package/dist/{chunk-ODJCZ27I.js → chunk-N7HYNKK6.js} +35 -2
- package/dist/{chunk-4J2QEIUV.js → chunk-NTFQ36UN.js} +4 -30
- package/dist/chunk-NU6LVKGS.js +15 -0
- package/dist/chunk-P2N6K2IV.js +20 -0
- package/dist/{chunk-QQRDUMB2.js → chunk-QCJWPXLH.js} +11 -11
- package/dist/{chunk-QELZ6TEJ.js → chunk-UD2CXYSJ.js} +39 -3
- package/dist/{chunk-UJHOUZAL.js → chunk-V4EMDPCO.js} +2 -5
- package/dist/chunk-VNGXRYFF.js +9 -0
- package/dist/{chunk-HNOAZWFH.js → chunk-WGCWJOT2.js} +2 -0
- package/dist/chunk-X6W44WHO.js +26 -0
- package/dist/chunk-ZUSM4VW4.js +197 -0
- package/dist/client/EventTransport.d.ts +23 -7
- package/dist/client/EventTransport.js +1 -2
- package/dist/client/awaiting.js +0 -1
- package/dist/client/channel-transport.d.ts +6 -6
- package/dist/client/channel-transport.js +0 -1
- package/dist/client/circuit-store.d.ts +16 -5
- package/dist/client/circuit-store.js +2 -3
- package/dist/client/client-kernel.d.ts +36 -15
- package/dist/client/declared-input-dispatch.d.ts +19 -2
- package/dist/client/declared-input-dispatch.js +1 -2
- package/dist/client/inbound-dispatch.d.ts +21 -2
- package/dist/client/inbound-dispatch.js +1 -2
- package/dist/client/local-fold.d.ts +15 -8
- package/dist/client/local-fold.js +1 -2
- package/dist/client/render-sigils.js +0 -1
- package/dist/client/state-book.d.ts +9 -16
- package/dist/client/state-book.js +1 -2
- package/dist/client/trait-mount-error.js +0 -1
- package/dist/credentials/env-vars.d.ts +5 -1
- package/dist/credentials/env-vars.js +1 -3
- package/dist/credentials/scope.d.ts +8 -7
- package/dist/credentials/scope.js +0 -1
- package/dist/credentials/vault.d.ts +142 -0
- package/dist/credentials/vault.js +1 -0
- package/dist/effects/in-flight-calls.js +0 -1
- package/dist/effects/on-device-model.js +0 -1
- package/dist/events/EventBus.d.ts +1 -4
- package/dist/events/EventBus.js +0 -1
- package/dist/events/emit-stamp.js +0 -1
- package/dist/index.d.ts +25 -42
- package/dist/index.js +27 -45
- package/dist/kernel/decode.d.ts +8 -10
- package/dist/kernel/decode.js +1 -2
- package/dist/kernel/engine.d.ts +132 -31
- package/dist/kernel/engine.js +7 -9
- package/dist/kernel/frame-applier.d.ts +8 -7
- package/dist/kernel/frame-applier.js +1 -2
- package/dist/kernel/host.d.ts +127 -16
- package/dist/kernel/host.js +4 -7
- package/dist/kernel/lane.d.ts +1 -22
- package/dist/kernel/lane.js +1 -2
- package/dist/kernel/os-fetch-port.d.ts +7 -0
- package/dist/kernel/os-fetch-port.js +3 -0
- package/dist/kernel/os-port.d.ts +30 -8
- package/dist/kernel/os-port.js +1 -2
- package/dist/kernel/program-effects.d.ts +11 -28
- package/dist/kernel/program-effects.js +1 -2
- package/dist/kernel/secret-ports.d.ts +139 -0
- package/dist/kernel/secret-ports.js +2 -0
- package/dist/kernel/wire.d.ts +50 -12
- package/dist/loader/fetch-loader.d.ts +26 -0
- package/dist/loader/fetch-loader.js +1 -0
- package/dist/loader/lazy-page.js +0 -1
- package/dist/loader/schema-loader.d.ts +1 -17
- package/dist/persistence/native-memory.js +0 -1
- package/dist/runtime/entities/declaredCollections.d.ts +6 -0
- package/dist/runtime/entities/declaredCollections.js +1 -0
- package/dist/runtime/evaluation/local-store-transport.d.ts +14 -23
- package/dist/runtime/evaluation/local-store-transport.js +9 -13
- package/dist/runtime/evaluation/residence-transport.d.ts +3 -3
- package/dist/runtime/evaluation/residence-transport.js +1 -2
- package/dist/runtime/evaluation/routed-persistence.js +0 -1
- package/dist/runtime/events/identity/routing.d.ts +2 -53
- package/dist/runtime/events/identity/routing.js +1 -2
- package/dist/runtime/types.d.ts +5 -205
- package/dist/runtime/types.js +1 -2
- package/dist/service/default-call-service.js +0 -1
- package/dist/service/service-provider.js +0 -1
- package/package.json +8 -5
- package/dist/chunk-2JU7Y4KU.js +0 -21
- package/dist/chunk-46RWK2B5.js +0 -28
- package/dist/chunk-4ZICQ5PM.js +0 -192
- package/dist/chunk-53IPZXDP.js +0 -76
- package/dist/chunk-5D63EMO5.js +0 -16
- package/dist/chunk-CPSQXEJ6.js +0 -55
- package/dist/chunk-CQP5XAX6.js +0 -173
- package/dist/chunk-CROS2GEX.js +0 -49
- package/dist/chunk-D4XJTBLB.js +0 -217
- package/dist/chunk-D5USD2EX.js +0 -232
- package/dist/chunk-EV56K4GB.js +0 -63
- package/dist/chunk-FQ6IZMIU.js +0 -10
- package/dist/chunk-HMK6YMQS.js +0 -135
- package/dist/chunk-IHQLE5M7.js +0 -62
- package/dist/chunk-JFWFDUTR.js +0 -35
- package/dist/chunk-MHYSHSRG.js +0 -54
- package/dist/chunk-MLKGABMK.js +0 -7
- package/dist/chunk-NAECVIAR.js +0 -322
- package/dist/chunk-Q7JK4KY7.js +0 -9
- package/dist/chunk-RBUMDYFS.js +0 -681
- package/dist/chunk-SAS5KKCR.js +0 -43
- package/dist/chunk-SWPDU752.js +0 -28
- package/dist/chunk-T775TUCD.js +0 -18
- package/dist/chunk-VMOBW7RK.js +0 -21
- package/dist/chunk-WNPNNYXY.js +0 -22
- package/dist/chunk-XB5GYODW.js +0 -28
- package/dist/chunk-YL2SO5TP.js +0 -334
- package/dist/chunk-YO4LWS3I.js +0 -606
- package/dist/chunk-ZAQSS47X.js +0 -157
- package/dist/chunk-ZCQUUJIF.js +0 -129
- package/dist/client/ServerBridge.d.ts +0 -126
- package/dist/client/ServerBridge.js +0 -3
- package/dist/credentials/seed.d.ts +0 -21
- package/dist/credentials/seed.js +0 -2
- package/dist/credentials/store.d.ts +0 -110
- package/dist/credentials/store.js +0 -2
- package/dist/index-hT1xCdTq.d.ts +0 -46
- package/dist/kernel/beacon.d.ts +0 -32
- package/dist/kernel/beacon.js +0 -2
- package/dist/kernel/http.d.ts +0 -302
- package/dist/kernel/http.js +0 -6
- package/dist/kernel/oauth-effects.d.ts +0 -25
- package/dist/kernel/oauth-effects.js +0 -7
- package/dist/kernel/oauth-port.d.ts +0 -31
- package/dist/kernel/oauth-port.js +0 -2
- package/dist/loader/http-loader.d.ts +0 -111
- package/dist/loader/http-loader.js +0 -2
- package/dist/runtime/effects/composition/compose-behaviors.d.ts +0 -58
- package/dist/runtime/effects/composition/compose-behaviors.js +0 -4
- package/dist/runtime/effects/composition/event-wiring.d.ts +0 -38
- package/dist/runtime/effects/composition/event-wiring.js +0 -2
- package/dist/runtime/effects/composition/index.d.ts +0 -5
- package/dist/runtime/effects/composition/index.js +0 -6
- package/dist/runtime/effects/composition/layout-strategy.d.ts +0 -35
- package/dist/runtime/effects/composition/layout-strategy.js +0 -2
- package/dist/runtime/effects/composition/pipe.d.ts +0 -25
- package/dist/runtime/effects/composition/pipe.js +0 -2
- package/dist/runtime/entities/mockStoreSeed.d.ts +0 -56
- package/dist/runtime/entities/mockStoreSeed.js +0 -3
- package/dist/runtime/entities/seedBrowserStore.d.ts +0 -28
- package/dist/runtime/entities/seedBrowserStore.js +0 -2
- package/dist/runtime/entities/std-mock-seed.d.ts +0 -87
- package/dist/runtime/entities/std-mock-seed.js +0 -2
- package/dist/runtime/time/TickScheduler.d.ts +0 -77
- package/dist/runtime/time/TickScheduler.js +0 -3
- package/dist/runtime/time/cron.d.ts +0 -25
- package/dist/runtime/time/cron.js +0 -2
- package/dist/runtime/time/duration.d.ts +0 -20
- package/dist/runtime/time/duration.js +0 -2
- package/dist/runtime/traits/OrbitalTraitParsing.d.ts +0 -34
- package/dist/runtime/traits/OrbitalTraitParsing.js +0 -2
- package/dist/runtime/traits/listen-targets.d.ts +0 -16
- package/dist/runtime/traits/listen-targets.js +0 -3
- package/dist/runtime/traits/trait-index.d.ts +0 -35
- package/dist/runtime/traits/trait-index.js +0 -3
package/dist/chunk-SAS5KKCR.js
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { unwrapTraitRef, normalizeCallSiteConfigToValues, isInlineTrait, isEntityCall } from '@almadar/core';
|
|
2
|
-
|
|
3
|
-
// src/runtime/traits/OrbitalTraitParsing.ts
|
|
4
|
-
function parseOrbitalTraits(orbital) {
|
|
5
|
-
const configByTrait = /* @__PURE__ */ new Map();
|
|
6
|
-
const unwrapped = (orbital.traits || []).map((t) => {
|
|
7
|
-
const { trait, config } = unwrapTraitRef(t);
|
|
8
|
-
const normalizedConfig = normalizeCallSiteConfigToValues(config);
|
|
9
|
-
if (normalizedConfig && typeof trait !== "string" && isInlineTrait(trait) && trait.name) {
|
|
10
|
-
configByTrait.set(trait.name, normalizedConfig);
|
|
11
|
-
}
|
|
12
|
-
return trait;
|
|
13
|
-
});
|
|
14
|
-
const inlineTraits = unwrapped.filter(isInlineTrait);
|
|
15
|
-
const traits = inlineTraits.map((t) => {
|
|
16
|
-
const sm = t.stateMachine;
|
|
17
|
-
return {
|
|
18
|
-
...t.id !== void 0 ? { id: t.id } : {},
|
|
19
|
-
name: t.name,
|
|
20
|
-
states: sm?.states || [],
|
|
21
|
-
transitions: sm?.transitions || [],
|
|
22
|
-
listens: t.listens
|
|
23
|
-
};
|
|
24
|
-
});
|
|
25
|
-
const entityRef = orbital.entity;
|
|
26
|
-
let entity;
|
|
27
|
-
if (typeof entityRef === "string") {
|
|
28
|
-
entity = { name: entityRef, fields: [] };
|
|
29
|
-
} else if (isEntityCall(entityRef)) {
|
|
30
|
-
const fallbackName = entityRef.name ?? entityRef.extends.replace(/\.entity$/, "");
|
|
31
|
-
entity = {
|
|
32
|
-
name: fallbackName,
|
|
33
|
-
fields: entityRef.fields ?? [],
|
|
34
|
-
...entityRef.persistence ? { persistence: entityRef.persistence } : {},
|
|
35
|
-
...entityRef.collection ? { collection: entityRef.collection } : {}
|
|
36
|
-
};
|
|
37
|
-
} else {
|
|
38
|
-
entity = entityRef;
|
|
39
|
-
}
|
|
40
|
-
return { traits, inlineTraits, configByTrait, entity };
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export { parseOrbitalTraits };
|
package/dist/chunk-SWPDU752.js
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { isJsonObject } from '@almadar/core';
|
|
2
|
-
|
|
3
|
-
// src/credentials/seed.ts
|
|
4
|
-
function planRows(json) {
|
|
5
|
-
const rows = JSON.parse(json);
|
|
6
|
-
if (!Array.isArray(rows)) throw new Error("the kernel seed plan is not a list");
|
|
7
|
-
return rows.map((row) => {
|
|
8
|
-
if (!isJsonObject(row) || typeof row.service !== "string" || typeof row.envVar !== "string") {
|
|
9
|
-
throw new Error("the kernel seed plan holds a row that is not { service, envVar }");
|
|
10
|
-
}
|
|
11
|
-
return { service: row.service, envVar: row.envVar };
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
async function seedCredentialStore(store, declared, env, kernel) {
|
|
15
|
-
if (!store.enabled) return 0;
|
|
16
|
-
const names = [...new Set(declared.map((d) => d.envVar))];
|
|
17
|
-
const held = names.filter((name) => store.resolve(name) !== void 0);
|
|
18
|
-
const present = names.filter((name) => (env[name] ?? "") !== "");
|
|
19
|
-
const plan = planRows(kernel.credentialSeedPlan(JSON.stringify(declared), JSON.stringify(held), JSON.stringify(present)));
|
|
20
|
-
for (const { service, envVar } of plan) {
|
|
21
|
-
const value = env[envVar];
|
|
22
|
-
if (value === void 0) throw new Error(`the kernel seeded ${envVar}, which the env does not hold`);
|
|
23
|
-
await store.set(service, envVar, value);
|
|
24
|
-
}
|
|
25
|
-
return plan.length;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export { seedCredentialStore };
|
package/dist/chunk-T775TUCD.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
// src/runtime/entities/seedBrowserStore.ts
|
|
2
|
-
async function isEmpty(store, entityType) {
|
|
3
|
-
return store.countRows ? await store.countRows(entityType) === 0 : (await store.list(entityType)).length === 0;
|
|
4
|
-
}
|
|
5
|
-
async function seedBrowserStore(store, entities, locale, host) {
|
|
6
|
-
const empty = [];
|
|
7
|
-
for (const entity of entities) {
|
|
8
|
-
if (entity.browser === true && await isEmpty(store, entity.name)) empty.push(entity);
|
|
9
|
-
}
|
|
10
|
-
if (empty.length === 0) return;
|
|
11
|
-
const program = {
|
|
12
|
-
name: "BrowserStoreSeed",
|
|
13
|
-
orbitals: empty.map((entity, index) => ({ name: `BrowserStore${index}`, entity, traits: [], pages: [] }))
|
|
14
|
-
};
|
|
15
|
-
await host.seeder.dataset(program, { nowMs: host.nowMs, ...locale !== void 0 ? { locale } : {} });
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export { seedBrowserStore };
|
package/dist/chunk-VMOBW7RK.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
// src/kernel/beacon.ts
|
|
2
|
-
async function deliverBeacon(url, text, ports) {
|
|
3
|
-
try {
|
|
4
|
-
if (ports.queue !== void 0 && ports.queue(url, text)) return { via: "queue" };
|
|
5
|
-
} catch {
|
|
6
|
-
}
|
|
7
|
-
try {
|
|
8
|
-
const { status } = await ports.fetch(url, {
|
|
9
|
-
method: "POST",
|
|
10
|
-
body: text,
|
|
11
|
-
keepalive: true,
|
|
12
|
-
mode: "cors",
|
|
13
|
-
headers: { "Content-Type": "text/plain" }
|
|
14
|
-
});
|
|
15
|
-
return { via: "fetch", status };
|
|
16
|
-
} catch {
|
|
17
|
-
return { via: "fetch", status: null };
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export { deliverBeacon };
|
package/dist/chunk-WNPNNYXY.js
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { getStdEffectOperators, getOperatorRunsOn } from '@almadar/std/registry';
|
|
2
|
-
|
|
3
|
-
// src/runtime/types.ts
|
|
4
|
-
function isEffectTuple(value) {
|
|
5
|
-
return Array.isArray(value) && typeof value[0] === "string";
|
|
6
|
-
}
|
|
7
|
-
var EFFECT_ALIASES = { render: "render-ui" };
|
|
8
|
-
function withAliases(ops) {
|
|
9
|
-
const aliases = Object.keys(EFFECT_ALIASES).filter((alias) => ops.includes(EFFECT_ALIASES[alias]));
|
|
10
|
-
return [...ops, ...aliases].sort();
|
|
11
|
-
}
|
|
12
|
-
function effectsNotOn(site) {
|
|
13
|
-
return withAliases(getStdEffectOperators().filter((op) => getOperatorRunsOn(op) !== site));
|
|
14
|
-
}
|
|
15
|
-
var HANDLER_MANIFEST = {
|
|
16
|
-
client: effectsNotOn("server"),
|
|
17
|
-
server: effectsNotOn("client"),
|
|
18
|
-
test: withAliases(getStdEffectOperators()),
|
|
19
|
-
ssr: withAliases(["render-ui", "fetch", "emit", "set", "log", "ref", "deref"])
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
export { HANDLER_MANIFEST, isEffectTuple };
|
package/dist/chunk-XB5GYODW.js
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { parseListenSource } from './chunk-IHQLE5M7.js';
|
|
2
|
-
import { applyListenMapping, kernelEvaluator, toWireValue } from '@almadar/core';
|
|
3
|
-
|
|
4
|
-
function listenGuardHolds(guard, payload) {
|
|
5
|
-
const outcome = kernelEvaluator().evaluateGuard({ payload: toWireValue(payload ?? {}) }, guard);
|
|
6
|
-
return outcome.kind === "value" && outcome.value;
|
|
7
|
-
}
|
|
8
|
-
function collectListenerTargets(traitIndex, sourceStamp, event, payload) {
|
|
9
|
-
const targets = [];
|
|
10
|
-
for (const [listenerName, listenerEntry] of traitIndex.byName) {
|
|
11
|
-
for (const listener of listenerEntry.traitDef.listens ?? []) {
|
|
12
|
-
const { bareEvent, matcher } = parseListenSource(listener, listenerEntry.orbitalName);
|
|
13
|
-
if (bareEvent !== event || !matcher(sourceStamp)) continue;
|
|
14
|
-
if (listener.guard !== void 0 && !listenGuardHolds(listener.guard, payload)) continue;
|
|
15
|
-
targets.push({
|
|
16
|
-
listenerTrait: listenerName,
|
|
17
|
-
entry: listenerEntry,
|
|
18
|
-
listener,
|
|
19
|
-
triggers: listener.triggers,
|
|
20
|
-
...listener.triggersId !== void 0 ? { triggersId: listener.triggersId } : {},
|
|
21
|
-
payload: applyListenMapping(listener.payloadMapping, payload)
|
|
22
|
-
});
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
return targets;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export { collectListenerTargets };
|
package/dist/chunk-YL2SO5TP.js
DELETED
|
@@ -1,334 +0,0 @@
|
|
|
1
|
-
import { OrbitalSchemaSchema } from '@almadar/core';
|
|
2
|
-
|
|
3
|
-
// src/loader/http-loader.ts
|
|
4
|
-
function isAbsoluteUrl(base) {
|
|
5
|
-
return /^[a-z][a-z0-9+.-]*:/i.test(base);
|
|
6
|
-
}
|
|
7
|
-
var HttpImportChain = class _HttpImportChain {
|
|
8
|
-
chain = [];
|
|
9
|
-
/**
|
|
10
|
-
* Try to add a path to the chain.
|
|
11
|
-
* @returns Error message if circular, null if OK
|
|
12
|
-
*/
|
|
13
|
-
push(absolutePath) {
|
|
14
|
-
if (this.chain.includes(absolutePath)) {
|
|
15
|
-
const cycle = [
|
|
16
|
-
...this.chain.slice(this.chain.indexOf(absolutePath)),
|
|
17
|
-
absolutePath
|
|
18
|
-
];
|
|
19
|
-
return `Circular import detected: ${cycle.join(" -> ")}`;
|
|
20
|
-
}
|
|
21
|
-
this.chain.push(absolutePath);
|
|
22
|
-
return null;
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Remove the last path from the chain.
|
|
26
|
-
*/
|
|
27
|
-
pop() {
|
|
28
|
-
this.chain.pop();
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Clone the chain for nested loading.
|
|
32
|
-
*/
|
|
33
|
-
clone() {
|
|
34
|
-
const newChain = new _HttpImportChain();
|
|
35
|
-
newChain.chain = [...this.chain];
|
|
36
|
-
return newChain;
|
|
37
|
-
}
|
|
38
|
-
};
|
|
39
|
-
var HttpLoaderCache = class {
|
|
40
|
-
cache = /* @__PURE__ */ new Map();
|
|
41
|
-
get(url) {
|
|
42
|
-
return this.cache.get(url);
|
|
43
|
-
}
|
|
44
|
-
set(url, schema) {
|
|
45
|
-
this.cache.set(url, schema);
|
|
46
|
-
}
|
|
47
|
-
has(url) {
|
|
48
|
-
return this.cache.has(url);
|
|
49
|
-
}
|
|
50
|
-
clear() {
|
|
51
|
-
this.cache.clear();
|
|
52
|
-
}
|
|
53
|
-
get size() {
|
|
54
|
-
return this.cache.size;
|
|
55
|
-
}
|
|
56
|
-
};
|
|
57
|
-
var HttpLoader = class {
|
|
58
|
-
options;
|
|
59
|
-
cache;
|
|
60
|
-
constructor(options) {
|
|
61
|
-
this.options = {
|
|
62
|
-
basePath: options.basePath,
|
|
63
|
-
stdLibPath: options.stdLibPath ?? "",
|
|
64
|
-
scopedPaths: options.scopedPaths ?? {},
|
|
65
|
-
fetchOptions: options.fetchOptions,
|
|
66
|
-
timeout: options.timeout ?? 3e4,
|
|
67
|
-
credentials: options.credentials ?? "same-origin"
|
|
68
|
-
};
|
|
69
|
-
this.cache = new HttpLoaderCache();
|
|
70
|
-
}
|
|
71
|
-
/**
|
|
72
|
-
* Load a schema from an import path.
|
|
73
|
-
*/
|
|
74
|
-
async load(importPath, fromPath, chain) {
|
|
75
|
-
const importChain = chain ?? new HttpImportChain();
|
|
76
|
-
const resolveResult = this.resolvePath(importPath, fromPath);
|
|
77
|
-
if (!resolveResult.success) {
|
|
78
|
-
return resolveResult;
|
|
79
|
-
}
|
|
80
|
-
const absoluteUrl = resolveResult.data;
|
|
81
|
-
const circularError = importChain.push(absoluteUrl);
|
|
82
|
-
if (circularError) {
|
|
83
|
-
return { success: false, error: circularError };
|
|
84
|
-
}
|
|
85
|
-
try {
|
|
86
|
-
const cached = this.cache.get(absoluteUrl);
|
|
87
|
-
if (cached) {
|
|
88
|
-
return { success: true, data: cached };
|
|
89
|
-
}
|
|
90
|
-
const loadResult = await this.fetchSchema(absoluteUrl);
|
|
91
|
-
if (!loadResult.success) {
|
|
92
|
-
return loadResult;
|
|
93
|
-
}
|
|
94
|
-
const loaded = {
|
|
95
|
-
schema: loadResult.data,
|
|
96
|
-
sourcePath: absoluteUrl,
|
|
97
|
-
importPath
|
|
98
|
-
};
|
|
99
|
-
this.cache.set(absoluteUrl, loaded);
|
|
100
|
-
return { success: true, data: loaded };
|
|
101
|
-
} finally {
|
|
102
|
-
importChain.pop();
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
/**
|
|
106
|
-
* Load a specific orbital from a schema by name.
|
|
107
|
-
*/
|
|
108
|
-
async loadOrbital(importPath, orbitalName, fromPath, chain) {
|
|
109
|
-
const schemaResult = await this.load(importPath, fromPath, chain);
|
|
110
|
-
if (!schemaResult.success) {
|
|
111
|
-
return schemaResult;
|
|
112
|
-
}
|
|
113
|
-
const schema = schemaResult.data.schema;
|
|
114
|
-
let orbital;
|
|
115
|
-
if (orbitalName) {
|
|
116
|
-
const found = schema.orbitals.find(
|
|
117
|
-
(o) => o.name === orbitalName
|
|
118
|
-
);
|
|
119
|
-
if (!found) {
|
|
120
|
-
return {
|
|
121
|
-
success: false,
|
|
122
|
-
error: `Orbital "${orbitalName}" not found in ${importPath}. Available: ${schema.orbitals.map((o) => o.name).join(", ")}`
|
|
123
|
-
};
|
|
124
|
-
}
|
|
125
|
-
orbital = found;
|
|
126
|
-
} else {
|
|
127
|
-
if (schema.orbitals.length === 0) {
|
|
128
|
-
return {
|
|
129
|
-
success: false,
|
|
130
|
-
error: `No orbitals found in ${importPath}`
|
|
131
|
-
};
|
|
132
|
-
}
|
|
133
|
-
orbital = schema.orbitals[0];
|
|
134
|
-
}
|
|
135
|
-
return {
|
|
136
|
-
success: true,
|
|
137
|
-
data: {
|
|
138
|
-
orbital,
|
|
139
|
-
orbitals: schema.orbitals,
|
|
140
|
-
...schema.config ? { schemaConfig: schema.config } : {},
|
|
141
|
-
sourcePath: schemaResult.data.sourcePath,
|
|
142
|
-
importPath
|
|
143
|
-
}
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
/**
|
|
147
|
-
* Resolve an import path to an absolute URL.
|
|
148
|
-
*/
|
|
149
|
-
resolvePath(importPath, fromPath) {
|
|
150
|
-
if (importPath.startsWith("http://") || importPath.startsWith("https://")) {
|
|
151
|
-
return { success: true, data: importPath };
|
|
152
|
-
}
|
|
153
|
-
if (importPath.startsWith("std/")) {
|
|
154
|
-
return this.resolveStdPath(importPath);
|
|
155
|
-
}
|
|
156
|
-
if (importPath.startsWith("@")) {
|
|
157
|
-
return this.resolveScopedPath(importPath);
|
|
158
|
-
}
|
|
159
|
-
if (importPath.startsWith("./") || importPath.startsWith("../")) {
|
|
160
|
-
return this.resolveRelativePath(importPath, fromPath);
|
|
161
|
-
}
|
|
162
|
-
return this.resolveRelativePath(`./${importPath}`, fromPath);
|
|
163
|
-
}
|
|
164
|
-
/**
|
|
165
|
-
* Resolve a standard library path.
|
|
166
|
-
*/
|
|
167
|
-
resolveStdPath(importPath) {
|
|
168
|
-
if (!this.options.stdLibPath) {
|
|
169
|
-
return {
|
|
170
|
-
success: false,
|
|
171
|
-
error: `Standard library URL not configured. Cannot load: ${importPath}`
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
const relativePath = importPath.slice(4);
|
|
175
|
-
let absoluteUrl = this.joinUrl(this.options.stdLibPath, relativePath);
|
|
176
|
-
if (!absoluteUrl.endsWith(".orb")) {
|
|
177
|
-
absoluteUrl += ".orb";
|
|
178
|
-
}
|
|
179
|
-
return { success: true, data: absoluteUrl };
|
|
180
|
-
}
|
|
181
|
-
/**
|
|
182
|
-
* Resolve a scoped package path.
|
|
183
|
-
*/
|
|
184
|
-
resolveScopedPath(importPath) {
|
|
185
|
-
const match = importPath.match(/^(@[^/]+)/);
|
|
186
|
-
if (!match) {
|
|
187
|
-
return {
|
|
188
|
-
success: false,
|
|
189
|
-
error: `Invalid scoped package path: ${importPath}`
|
|
190
|
-
};
|
|
191
|
-
}
|
|
192
|
-
const scope = match[1];
|
|
193
|
-
const scopeRoot = this.options.scopedPaths[scope];
|
|
194
|
-
if (!scopeRoot) {
|
|
195
|
-
return {
|
|
196
|
-
success: false,
|
|
197
|
-
error: `Scoped package "${scope}" not configured. Available: ${Object.keys(this.options.scopedPaths).join(", ") || "none"}`
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
const relativePath = importPath.slice(scope.length + 1);
|
|
201
|
-
let absoluteUrl = this.joinUrl(scopeRoot, relativePath);
|
|
202
|
-
if (!absoluteUrl.endsWith(".orb")) {
|
|
203
|
-
absoluteUrl += ".orb";
|
|
204
|
-
}
|
|
205
|
-
return { success: true, data: absoluteUrl };
|
|
206
|
-
}
|
|
207
|
-
/**
|
|
208
|
-
* Resolve a relative path.
|
|
209
|
-
*/
|
|
210
|
-
resolveRelativePath(importPath, fromPath) {
|
|
211
|
-
const baseUrl = fromPath ? this.getParentUrl(fromPath) : this.options.basePath;
|
|
212
|
-
let absoluteUrl = this.joinUrl(baseUrl, importPath);
|
|
213
|
-
if (!absoluteUrl.endsWith(".orb")) {
|
|
214
|
-
absoluteUrl += ".orb";
|
|
215
|
-
}
|
|
216
|
-
return { success: true, data: absoluteUrl };
|
|
217
|
-
}
|
|
218
|
-
/**
|
|
219
|
-
* Fetch and parse an OrbitalSchema from a URL.
|
|
220
|
-
*/
|
|
221
|
-
async fetchSchema(url) {
|
|
222
|
-
try {
|
|
223
|
-
const controller = new AbortController();
|
|
224
|
-
const timeoutId = setTimeout(
|
|
225
|
-
() => controller.abort(),
|
|
226
|
-
this.options.timeout
|
|
227
|
-
);
|
|
228
|
-
try {
|
|
229
|
-
const response = await fetch(url, {
|
|
230
|
-
...this.options.fetchOptions,
|
|
231
|
-
credentials: this.options.credentials,
|
|
232
|
-
signal: controller.signal,
|
|
233
|
-
headers: {
|
|
234
|
-
Accept: "application/json",
|
|
235
|
-
...this.options.fetchOptions?.headers
|
|
236
|
-
}
|
|
237
|
-
});
|
|
238
|
-
if (!response.ok) {
|
|
239
|
-
return {
|
|
240
|
-
success: false,
|
|
241
|
-
error: `HTTP ${response.status}: ${response.statusText} for ${url}`
|
|
242
|
-
};
|
|
243
|
-
}
|
|
244
|
-
const text = await response.text();
|
|
245
|
-
let data;
|
|
246
|
-
try {
|
|
247
|
-
data = JSON.parse(text);
|
|
248
|
-
} catch (e) {
|
|
249
|
-
return {
|
|
250
|
-
success: false,
|
|
251
|
-
error: `Invalid JSON in ${url}: ${e instanceof Error ? e.message : String(e)}`
|
|
252
|
-
};
|
|
253
|
-
}
|
|
254
|
-
const parseResult = OrbitalSchemaSchema.safeParse(data);
|
|
255
|
-
if (!parseResult.success) {
|
|
256
|
-
const errors = parseResult.error.issues.map((e) => ` - ${e.path.map(String).join(".")}: ${e.message}`).join("\n");
|
|
257
|
-
return {
|
|
258
|
-
success: false,
|
|
259
|
-
error: `Invalid schema in ${url}:
|
|
260
|
-
${errors}`
|
|
261
|
-
};
|
|
262
|
-
}
|
|
263
|
-
return { success: true, data: parseResult.data };
|
|
264
|
-
} finally {
|
|
265
|
-
clearTimeout(timeoutId);
|
|
266
|
-
}
|
|
267
|
-
} catch (e) {
|
|
268
|
-
if (e instanceof Error && e.name === "AbortError") {
|
|
269
|
-
return {
|
|
270
|
-
success: false,
|
|
271
|
-
error: `Request timeout for ${url} (${this.options.timeout}ms)`
|
|
272
|
-
};
|
|
273
|
-
}
|
|
274
|
-
return {
|
|
275
|
-
success: false,
|
|
276
|
-
error: `Failed to fetch ${url}: ${e instanceof Error ? e.message : String(e)}`
|
|
277
|
-
};
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
/**
|
|
281
|
-
* Join URL parts, handling relative paths and trailing slashes.
|
|
282
|
-
*/
|
|
283
|
-
joinUrl(base, path) {
|
|
284
|
-
if (path.startsWith("http://") || path.startsWith("https://")) {
|
|
285
|
-
return path;
|
|
286
|
-
}
|
|
287
|
-
if (isAbsoluteUrl(base)) return new URL(path, base.endsWith("/") ? base : base + "/").href;
|
|
288
|
-
const normalizedBase = base.endsWith("/") ? base.slice(0, -1) : base;
|
|
289
|
-
const normalizedPath = path.startsWith("/") ? path : "/" + path;
|
|
290
|
-
if (normalizedPath.startsWith("/./")) {
|
|
291
|
-
return normalizedBase + normalizedPath.slice(2);
|
|
292
|
-
}
|
|
293
|
-
if (normalizedPath.startsWith("/../")) {
|
|
294
|
-
const baseParts = normalizedBase.split("/");
|
|
295
|
-
baseParts.pop();
|
|
296
|
-
return baseParts.join("/") + normalizedPath.slice(3);
|
|
297
|
-
}
|
|
298
|
-
return normalizedBase + normalizedPath;
|
|
299
|
-
}
|
|
300
|
-
/**
|
|
301
|
-
* Get parent URL (directory) from a URL.
|
|
302
|
-
*/
|
|
303
|
-
getParentUrl(url) {
|
|
304
|
-
if (isAbsoluteUrl(url)) {
|
|
305
|
-
const urlObj = new URL(url);
|
|
306
|
-
const pathParts = urlObj.pathname.split("/");
|
|
307
|
-
pathParts.pop();
|
|
308
|
-
urlObj.pathname = pathParts.join("/");
|
|
309
|
-
return urlObj.href;
|
|
310
|
-
}
|
|
311
|
-
const lastSlash = url.lastIndexOf("/");
|
|
312
|
-
return lastSlash !== -1 ? url.slice(0, lastSlash) : url;
|
|
313
|
-
}
|
|
314
|
-
/**
|
|
315
|
-
* Clear the cache.
|
|
316
|
-
*/
|
|
317
|
-
clearCache() {
|
|
318
|
-
this.cache.clear();
|
|
319
|
-
}
|
|
320
|
-
/**
|
|
321
|
-
* Get cache statistics.
|
|
322
|
-
*/
|
|
323
|
-
getCacheStats() {
|
|
324
|
-
return { size: this.cache.size };
|
|
325
|
-
}
|
|
326
|
-
};
|
|
327
|
-
function createHttpLoader(basePath, options) {
|
|
328
|
-
return new HttpLoader({
|
|
329
|
-
basePath,
|
|
330
|
-
...options
|
|
331
|
-
});
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
export { HttpImportChain, HttpLoader, createHttpLoader };
|