@mosetta/runtime 0.0.10 → 0.0.11
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/package.json +3 -3
- package/src/bootstrap.ts +31 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mosetta/runtime",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.11",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "mosetta browser runtime: start() (resolver prolog, tree loading, holder), version resolver, safe tile loader, asset runtime. Framework-agnostic — the react mount (startAndMount) lives in @mosetta/react/start. Ships as an ordinary package tile; the root export is the component-facing asset surface.",
|
|
6
6
|
"type": "module",
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
"./naming": "./src/naming.js"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@mosetta/
|
|
21
|
-
"@mosetta/
|
|
20
|
+
"@mosetta/core": "0.0.11",
|
|
21
|
+
"@mosetta/di": "0.0.11"
|
|
22
22
|
},
|
|
23
23
|
"publishConfig": {
|
|
24
24
|
"access": "public"
|
package/src/bootstrap.ts
CHANGED
|
@@ -151,11 +151,15 @@ async function run(): Promise<IStartResult> {
|
|
|
151
151
|
// LOAD path.
|
|
152
152
|
const catalog = new Map<string, ITileDescriptor | null>(Object.entries(realmCatalog));
|
|
153
153
|
const DEP_PREFIX = '_ns_package_t_package_n_';
|
|
154
|
+
// where an entity outside the catalog was found: beside its importer, or at another tile host the
|
|
155
|
+
// realm knows — a block of a project's palette placed in the editor is loaded by the workbench's
|
|
156
|
+
// page, whose slice does not name it
|
|
157
|
+
const foundAt = new Map<string, string>();
|
|
154
158
|
// an entity lives with the code source its catalog entry names, the host when it names none; an
|
|
155
|
-
// entity outside the catalog —
|
|
159
|
+
// entity outside the catalog — where its descriptor was found, else the base it was asked from
|
|
156
160
|
const sourceBaseOf = (id: string, pb: string): string => {
|
|
157
161
|
const entry = catalog.get(id) ?? realmCatalog[id];
|
|
158
|
-
if (!entry) return pb;
|
|
162
|
+
if (!entry) return foundAt.get(id) ?? pb;
|
|
159
163
|
return (entry.provider ? sources[entry.provider] : base) || pb;
|
|
160
164
|
};
|
|
161
165
|
const entityFileUrl = (id: string, file: string, pb: string): string => new URL('modules/' + id + '/' + file, sourceBaseOf(id, pb)).href; // flat layout
|
|
@@ -165,12 +169,24 @@ async function run(): Promise<IStartResult> {
|
|
|
165
169
|
const sliceIntegrity = (id: string): string | undefined => realmCatalog[id]?.integrity;
|
|
166
170
|
const artifactUrl = (id: string, file: string, pb: string): string => versionedUrl(entityFileUrl(id, file, pb), sliceIntegrity(id));
|
|
167
171
|
const fetched = new Map<string, Promise<ITileDescriptor | null>>();
|
|
172
|
+
const descriptorAt = (id: string, at: string): Promise<ITileDescriptor | null> => fetch(new URL('modules/' + id + '/' + id + '.json', at).href)
|
|
173
|
+
.then((r) => (r.ok ? (r.json() as Promise<ITileDescriptor>) : null))
|
|
174
|
+
.catch(() => null);
|
|
175
|
+
// an entity outside the catalog: its co-located descriptor beside the base it was asked from, else
|
|
176
|
+
// at the realm's other tile hosts (the host last) — the first that has it is where it lives
|
|
168
177
|
const entityOf = (id: string, pb: string): Promise<ITileDescriptor | null> => {
|
|
169
178
|
if (catalog.has(id)) return Promise.resolve(catalog.get(id) ?? null);
|
|
170
179
|
if (!fetched.has(id)) {
|
|
171
|
-
fetched.set(id,
|
|
172
|
-
|
|
173
|
-
|
|
180
|
+
fetched.set(id, (async () => {
|
|
181
|
+
for (const at of new Set([foundAt.get(id) ?? pb, ...Object.values(sources), base])) {
|
|
182
|
+
const entity = await descriptorAt(id, at);
|
|
183
|
+
if (entity) {
|
|
184
|
+
foundAt.set(id, at);
|
|
185
|
+
return entity;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return null;
|
|
189
|
+
})());
|
|
174
190
|
}
|
|
175
191
|
return fetched.get(id)!;
|
|
176
192
|
};
|
|
@@ -299,15 +315,21 @@ async function run(): Promise<IStartResult> {
|
|
|
299
315
|
getModule: (ref: string): ILoadedTile | undefined => (handedOver.has(ref) ? loader.get(ref) : undefined),
|
|
300
316
|
loadModule: (ref: string, pb?: string): Promise<ILoadedTile> => {
|
|
301
317
|
const ready = handedOver.has(ref) ? loader.get(ref) : undefined;
|
|
302
|
-
if (ready) return Promise.resolve(ready);
|
|
318
|
+
if (ready && !ready.error) return Promise.resolve(ready);
|
|
303
319
|
const pending = handing.get(ref);
|
|
304
320
|
if (pending) return pending;
|
|
305
|
-
const
|
|
306
|
-
|
|
321
|
+
const handover = (async () => {
|
|
322
|
+
const asked = pb || providerOf(ref);
|
|
323
|
+
// an entity outside the catalog: found first — its code loads from where its descriptor lies
|
|
324
|
+
if (!catalog.has(ref) && !realmCatalog[ref]) await entityOf(ref, asked);
|
|
325
|
+
const target = sourceBaseOf(ref, asked);
|
|
326
|
+
// a failure before (asked where it does not lie) is tried again
|
|
327
|
+
loader.forget(ref);
|
|
328
|
+
const [, loaded] = await Promise.all([ensureCss(ref, target), loader.load(ref, target)]);
|
|
307
329
|
handedOver.add(ref);
|
|
308
330
|
handing.delete(ref);
|
|
309
331
|
return loaded;
|
|
310
|
-
});
|
|
332
|
+
})();
|
|
311
333
|
handing.set(ref, handover);
|
|
312
334
|
return handover;
|
|
313
335
|
},
|