fix(studio): render complete interactive gallery previews
This commit is contained in:
1 parent
c765d76a06
commit
9520651330
26 files changed
+5761
-39
No files matched your search
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@wrnexus/compiler",
|
||||
"version": "0.8.44",
|
||||
"version": "0.8.45",
|
||||
"type": "module",
|
||||
"main": "src/index.ts",
|
||||
"exports": {
|
||||
|
||||
@@ -520,20 +520,30 @@ export function generateBrowserModule(ast: PageAst): string {
|
||||
[...sharedState, ...sharedProps].filter((name) => identifierReferenced(source, name)),
|
||||
);
|
||||
}
|
||||
const sharedCommit = `const values = { ${sharedState.map((name) => `${JSON.stringify(name)}: ${name}`).join(", ")} };
|
||||
const pending = {};
|
||||
for (const name of Object.keys(values)) {
|
||||
if (!Object.is(values[name], committed[name])) { pending[name] = values[name]; committed[name] = values[name]; }
|
||||
const usedCommitNames = new Set([...sharedState, ...sharedProps, ...functionNames]);
|
||||
const commitName = (base: string) => {
|
||||
let name = base;
|
||||
while (usedCommitNames.has(name)) name += "_";
|
||||
usedCommitNames.add(name);
|
||||
return name;
|
||||
};
|
||||
const commitValues = commitName("__v"),
|
||||
commitPending = commitName("__p"),
|
||||
commitSnapshot = commitName("__c");
|
||||
const sharedCommit = `const ${commitValues} = { ${sharedState.map((name) => `${JSON.stringify(name)}: ${name}`).join(", ")} };
|
||||
const ${commitPending} = {};
|
||||
for (const name of Object.keys(${commitValues})) {
|
||||
if (!Object.is(${commitValues}[name], ${commitSnapshot}[name])) { ${commitPending}[name] = ${commitValues}[name]; ${commitSnapshot}[name] = ${commitValues}[name]; }
|
||||
}
|
||||
if (Object.keys(pending).length === 0) return;
|
||||
const apply = () => { for (const name of Object.keys(pending)) context.state[name] = pending[name]; };
|
||||
if (Object.keys(${commitPending}).length === 0) return;
|
||||
const apply = () => { for (const name of Object.keys(${commitPending})) context.state[name] = ${commitPending}[name]; };
|
||||
if (typeof context.batch === "function") context.batch(apply); else apply();`;
|
||||
const restores = [...sharedState, ...sharedProps]
|
||||
.map(
|
||||
(name) =>
|
||||
`${JSON.stringify(name)}:()=>{${
|
||||
sharedState.includes(name)
|
||||
? `${name} = context.state.${name}; committed.${name} = ${name};`
|
||||
? `${name} = context.state.${name}; ${commitSnapshot}.${name} = ${name};`
|
||||
: `${name} = context.props.${name};`
|
||||
}}`,
|
||||
)
|
||||
@@ -588,7 +598,7 @@ function __wrnexusCreateClientFunctions(context) {
|
||||
const props = context.props;
|
||||
const refs = context.refs;
|
||||
${apiBindings(ast)}
|
||||
const committed = { ${sharedState.map((name) => `${JSON.stringify(name)}: ${name}`).join(", ")} };
|
||||
const ${commitSnapshot} = { ${sharedState.map((name) => `${JSON.stringify(name)}: ${name}`).join(", ")} };
|
||||
const __wrnexusCommit = () => { ${sharedCommit} };
|
||||
const __wrnexusRestores = { ${restores} };
|
||||
const __wrnexusRestoreKeys = ${JSON.stringify(restoreKeys)};
|
||||
|
||||
@@ -11,6 +11,42 @@ const source = `component FunctionDefaults {
|
||||
}
|
||||
view { <button @click="choose()">Choose</button> }
|
||||
}`;
|
||||
|
||||
test("browser state named pending or values does not collide with commit bookkeeping", () => {
|
||||
const source = `component CommitNames {
|
||||
state pending = "ready"
|
||||
state values = 1
|
||||
state committed = false
|
||||
state __v = 3
|
||||
state __p = false
|
||||
state __c = "safe"
|
||||
functions {
|
||||
shared function status() { return pending + values + __c + __v }
|
||||
client function advance() { pending = "done"; values += 1; committed = true }
|
||||
}
|
||||
view { <button @click="advance()">Advance</button> }
|
||||
}`;
|
||||
const module = generateBrowserModule(parse(source));
|
||||
const functions = new Function(
|
||||
module.replace(/\bexport\s+(?=const|function)/g, "") + ";return __wrnexusClientFunctions;",
|
||||
)();
|
||||
const context = {
|
||||
state: { pending: "ready", values: 1, committed: false, __v: 3, __p: false, __c: "safe" },
|
||||
props: {},
|
||||
batch: (apply: () => void) => apply(),
|
||||
};
|
||||
expect(functions.status(context)).toBe("ready1safe3");
|
||||
functions.advance(context);
|
||||
expect(context.state).toEqual({
|
||||
pending: "done",
|
||||
values: 2,
|
||||
committed: true,
|
||||
__v: 3,
|
||||
__p: false,
|
||||
__c: "safe",
|
||||
});
|
||||
expect(functions.status(context)).toBe("done2safe3");
|
||||
});
|
||||
test("browser functions retain defaults, prior-argument references and prop references", () => {
|
||||
const module = generateBrowserModule(parse(source));
|
||||
const functions = new Function(
|
||||
|
||||
Reference in new issue
Block a user