release: WRNexusJS 0.2.31
This commit is contained in:
@@ -105,6 +105,19 @@ export interface ModeFunctionsBlock {
|
||||
body: string;
|
||||
}
|
||||
|
||||
export type LifecycleHookName = "mount" | "update" | "unmount";
|
||||
|
||||
export interface LifecycleBlock {
|
||||
mount?: string;
|
||||
update?: string;
|
||||
unmount?: string;
|
||||
}
|
||||
|
||||
export interface WatchBlock {
|
||||
state: string;
|
||||
body: string;
|
||||
}
|
||||
|
||||
export interface RealtimeHandler {
|
||||
event: string;
|
||||
args: string[];
|
||||
@@ -141,6 +154,8 @@ export interface PageAst {
|
||||
functions: string[];
|
||||
dataApis: DataApiBlock[];
|
||||
modeFunctions: ModeFunctionsBlock[];
|
||||
lifecycle: LifecycleBlock;
|
||||
watches: WatchBlock[];
|
||||
apis: ApiBlock[];
|
||||
realtimes: RealtimeBlock[];
|
||||
}
|
||||
@@ -210,6 +225,8 @@ export function parse(source: string): PageAst {
|
||||
const functions: string[] = [];
|
||||
const dataApis: DataApiBlock[] = [];
|
||||
const modeFunctions: ModeFunctionsBlock[] = [];
|
||||
const lifecycle: LifecycleBlock = {};
|
||||
const watches: WatchBlock[] = [];
|
||||
const apis: ApiBlock[] = [];
|
||||
const realtimes: RealtimeBlock[] = [];
|
||||
|
||||
@@ -339,6 +356,52 @@ export function parse(source: string): PageAst {
|
||||
styles.push(lx.readBalancedBraces());
|
||||
break;
|
||||
}
|
||||
case "lifecycle": {
|
||||
lx.next();
|
||||
expect("lbrace");
|
||||
|
||||
while (lx.peek().type !== "rbrace") {
|
||||
const hook = lx.peek();
|
||||
|
||||
if (hook.type === "eof") {
|
||||
throw new ParseError("Unexpected end of input inside lifecycle block");
|
||||
}
|
||||
|
||||
if (hook.type !== "ident") {
|
||||
throw new ParseError(`Expected a lifecycle hook at offset ${hook.pos}`);
|
||||
}
|
||||
|
||||
if (hook.value !== "mount" && hook.value !== "update" && hook.value !== "unmount") {
|
||||
throw new ParseError(`Unknown lifecycle hook '${hook.value}' at offset ${hook.pos}`);
|
||||
}
|
||||
|
||||
const hookName = hook.value as LifecycleHookName;
|
||||
|
||||
lx.next();
|
||||
|
||||
if (lifecycle[hookName] !== undefined) {
|
||||
throw new ParseError(`Duplicate lifecycle hook '${hookName}' at offset ${hook.pos}`);
|
||||
}
|
||||
|
||||
lifecycle[hookName] = lx.readBalancedBraces();
|
||||
}
|
||||
|
||||
expect("rbrace");
|
||||
break;
|
||||
}
|
||||
case "watch": {
|
||||
lx.next();
|
||||
|
||||
const stateName = expect("ident").value;
|
||||
const body = lx.readBalancedBraces();
|
||||
|
||||
watches.push({
|
||||
state: stateName,
|
||||
body,
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
case "functions": {
|
||||
lx.next();
|
||||
functions.push(lx.readBalancedBraces());
|
||||
@@ -350,6 +413,14 @@ export function parse(source: string): PageAst {
|
||||
}
|
||||
expect("rbrace");
|
||||
|
||||
const declaredStates = new Set(states.map((state) => state.name));
|
||||
|
||||
for (const watcher of watches) {
|
||||
if (!declaredStates.has(watcher.state)) {
|
||||
throw new ParseError(`Cannot watch undeclared state '${watcher.state}'`);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
type: "page",
|
||||
kind,
|
||||
@@ -363,6 +434,8 @@ export function parse(source: string): PageAst {
|
||||
functions,
|
||||
dataApis,
|
||||
modeFunctions,
|
||||
lifecycle,
|
||||
watches,
|
||||
apis,
|
||||
realtimes,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user