preserves-schema-browser.js
This commit is contained in:
parent
f6ddf0ca3b
commit
61cec52d46
|
@ -15,7 +15,7 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"regenerate": "rm -rf ./src/gen && yarn copy-schema && ../schema-cli/bin/preserves-schema-ts.js --output ./src/gen ./dist:*.prs",
|
"regenerate": "rm -rf ./src/gen && yarn copy-schema && ../schema-cli/bin/preserves-schema-ts.js --output ./src/gen ./dist:*.prs",
|
||||||
"clean": "rm -rf lib dist",
|
"clean": "rm -rf lib dist",
|
||||||
"prepare": "yarn compile && yarn rollup && yarn copy-schema",
|
"prepare": "yarn compile && yarn rollup && yarn copy-schema && cp preserves-schema-browser.js dist/",
|
||||||
"compile": "tsc",
|
"compile": "tsc",
|
||||||
"compile:watch": "yarn compile -w",
|
"compile:watch": "yarn compile -w",
|
||||||
"rollup": "rollup -c",
|
"rollup": "rollup -c",
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
(() => {
|
||||||
|
const I = new PreservesSchema.SchemaInterpreter();
|
||||||
|
|
||||||
|
globalThis.Schema = { __interpreter: I };
|
||||||
|
let schemaReady;
|
||||||
|
globalThis.SchemaReady = new Promise(res => schemaReady = res);
|
||||||
|
|
||||||
|
async function translateScripts() {
|
||||||
|
|
||||||
|
const schemaScripts =
|
||||||
|
Array.from(document.getElementsByTagName('script'))
|
||||||
|
.filter(s => (s.type === 'text/preserves+schema' ||
|
||||||
|
s.type === 'schema'));
|
||||||
|
|
||||||
|
for (const script of schemaScripts) {
|
||||||
|
function complain(message, detail) {
|
||||||
|
const e = new Error(message);
|
||||||
|
e.script = script;
|
||||||
|
e.detail = detail;
|
||||||
|
console.error(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
let sourceCodeBlob;
|
||||||
|
const sourceUrl = script.src || script.getAttribute('data-src') || false;
|
||||||
|
if (sourceUrl) {
|
||||||
|
const res = await fetch(sourceUrl);
|
||||||
|
if (res.ok) {
|
||||||
|
sourceCodeBlob = new Uint8Array(await res.arrayBuffer());
|
||||||
|
} else {
|
||||||
|
complain(`Failed to retrieve schema from ${sourceUrl}`, { res });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sourceCodeBlob = new TextEncoder().encode(script.innerHTML);
|
||||||
|
}
|
||||||
|
|
||||||
|
const schemaName = () => {
|
||||||
|
const n = script.getAttribute('name');
|
||||||
|
if (n === null) complain(`<script type="schema"> must have name attribute`);
|
||||||
|
return n;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (sourceCodeBlob[0] >= 128) {
|
||||||
|
// Binary Preserves blob
|
||||||
|
const value = Preserves.decode(sourceCodeBlob);
|
||||||
|
const bundle = PreservesSchema.Meta.toBundle(value);
|
||||||
|
if (bundle !== void 0) {
|
||||||
|
const prefixStr = script.getAttribute('prefix');
|
||||||
|
const bundlePrefix = (prefixStr ? prefixStr.split('.') : []).map(Symbol.for);
|
||||||
|
bundle.modules.forEach((schema, path) => {
|
||||||
|
const modulePath = [... bundlePrefix, ... path];
|
||||||
|
I.env.set(modulePath, schema);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const schema = PreservesSchema.Meta.toSchema(value);
|
||||||
|
if (schema !== void 0) {
|
||||||
|
const modulePath = schemaName().split('.').map(Symbol.for);
|
||||||
|
I.env.set(modulePath, schema);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Presumably text
|
||||||
|
const sourceCode = new TextDecoder('utf-8', { fatal: true }).decode(sourceCodeBlob);
|
||||||
|
const name = schemaName();
|
||||||
|
const schema = PreservesSchema.readSchema(sourceCode, { name });
|
||||||
|
const modulePath = name.split('.').map(Symbol.for);
|
||||||
|
I.env.set(modulePath, schema);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// I.env.forEach((_schema, path) => console.log(PreservesSchema.Meta.formatModulePath(path)));
|
||||||
|
|
||||||
|
for (const [modulePath, schema] of I.env) {
|
||||||
|
let container = Schema;
|
||||||
|
modulePath.slice(0, -1).forEach(n => {
|
||||||
|
if (!(n.description in container)) container[n.description] = {};
|
||||||
|
container = container[n.description];
|
||||||
|
});
|
||||||
|
container[modulePath[modulePath.length - 1].description] = moduleFor(modulePath, schema);
|
||||||
|
}
|
||||||
|
|
||||||
|
schemaReady();
|
||||||
|
}
|
||||||
|
|
||||||
|
function moduleFor(modulePath, schema) {
|
||||||
|
const { Meta, GenType, Type } = PreservesSchema;
|
||||||
|
const mod = {};
|
||||||
|
schema.definitions.forEach((d, n) => {
|
||||||
|
const definitionName = n.description;
|
||||||
|
const definitionId = Meta.jsId(definitionName);
|
||||||
|
mod[`${definitionId}`] = I.definitionConstructor(modulePath, n);
|
||||||
|
mod[`from${definitionId}`] = I.unparser(modulePath, n);
|
||||||
|
mod[`to${definitionId}`] = v => I.tryParse(modulePath, n, v);
|
||||||
|
mod[`as${definitionId}`] = v => I.parse(modulePath, n, v);
|
||||||
|
});
|
||||||
|
return mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.addEventListener('DOMContentLoaded', translateScripts);
|
||||||
|
})();
|
Loading…
Reference in New Issue