UNPKG

15.4 kBTypeScriptView Raw
1import { PresentArray } from '../array';
2import { Dict, Option } from '../core';
3import { CurriedType } from '../curry';
4
5export type TupleSyntax = Statement | TupleExpression;
6
7type JsonValue = string | number | boolean | JsonObject | JsonArray;
8
9interface JsonObject extends Dict<JsonValue> {}
10interface JsonArray extends Array<JsonValue> {}
11
12export type TemplateReference = Option<SerializedBlock>;
13export type YieldTo = number;
14
15/**
16 * A VariableResolutionContext explains how a variable name should be resolved.
17 */
18export const enum VariableResolutionContext {
19 Strict = 0,
20 AmbiguousAppend = 1,
21 AmbiguousAppendInvoke = 2,
22 AmbiguousInvoke = 3,
23 ResolveAsCallHead = 5,
24 ResolveAsModifierHead = 6,
25 ResolveAsComponentHead = 7,
26}
27
28export const enum SexpOpcodes {
29 // Statements
30 Append = 1,
31 TrustingAppend = 2,
32 Comment = 3,
33 Modifier = 4,
34 StrictModifier = 5,
35 Block = 6,
36 StrictBlock = 7,
37 Component = 8,
38
39 OpenElement = 10,
40 OpenElementWithSplat = 11,
41 FlushElement = 12,
42 CloseElement = 13,
43 StaticAttr = 14,
44 DynamicAttr = 15,
45 ComponentAttr = 16,
46
47 AttrSplat = 17,
48 Yield = 18,
49
50 DynamicArg = 20,
51 StaticArg = 21,
52 TrustingDynamicAttr = 22,
53 TrustingComponentAttr = 23,
54 StaticComponentAttr = 24,
55
56 Debugger = 26,
57
58 // Expressions
59 Undefined = 27,
60 Call = 28,
61 Concat = 29,
62
63 // Get
64 // Get a local value via symbol
65 GetSymbol = 30, // GetPath + 0-2,
66 // Template symbol are values that are in scope in the template in strict mode
67 GetTemplateSymbol = 32,
68 // Free variables are only keywords in strict mode
69 GetStrictFree = 31,
70
71 // `{{x}}` in append position (might be a helper or component invocation, otherwise fall back to `this`)
72 GetFreeAsComponentOrHelperHeadOrThisFallback = 34,
73 // a component or helper (`{{<expr> x}}` in append position)
74 GetFreeAsComponentOrHelperHead = 35,
75 // a helper or `this` fallback `attr={{x}}`
76 GetFreeAsHelperHeadOrThisFallback = 36,
77 // a helper or `this` fallback (deprecated) `@arg={{x}}`
78 GetFreeAsDeprecatedHelperHeadOrThisFallback = 99,
79 // a call head `(x)`
80 GetFreeAsHelperHead = 37,
81 GetFreeAsModifierHead = 38,
82 GetFreeAsComponentHead = 39,
83
84 // Keyword Statements
85 InElement = 40,
86 If = 41,
87 Each = 42,
88 With = 43,
89 Let = 44,
90 WithDynamicVars = 45,
91 InvokeComponent = 46,
92
93 // Keyword Expressions
94 HasBlock = 48,
95 HasBlockParams = 49,
96 Curry = 50,
97 Not = 51,
98 IfInline = 52,
99 GetDynamicVar = 53,
100 Log = 54,
101
102 GetStart = GetSymbol,
103 GetEnd = GetFreeAsComponentHead,
104 GetLooseFreeStart = GetFreeAsComponentOrHelperHeadOrThisFallback,
105 GetLooseFreeEnd = GetFreeAsComponentHead,
106 GetContextualFreeStart = GetFreeAsComponentOrHelperHeadOrThisFallback,
107}
108
109export type GetContextualFreeOp =
110 | SexpOpcodes.GetFreeAsComponentOrHelperHeadOrThisFallback
111 | SexpOpcodes.GetFreeAsComponentOrHelperHead
112 | SexpOpcodes.GetFreeAsHelperHeadOrThisFallback
113 | SexpOpcodes.GetFreeAsHelperHead
114 | SexpOpcodes.GetFreeAsModifierHead
115 | SexpOpcodes.GetFreeAsComponentHead
116 | SexpOpcodes.GetStrictFree;
117
118export type AttrOp =
119 | SexpOpcodes.StaticAttr
120 | SexpOpcodes.StaticComponentAttr
121 | SexpOpcodes.DynamicAttr
122 | SexpOpcodes.TrustingDynamicAttr
123 | SexpOpcodes.ComponentAttr
124 | SexpOpcodes.TrustingComponentAttr;
125
126export type StatementSexpOpcode = Statement[0];
127export type StatementSexpOpcodeMap = {
128 [TSexpOpcode in Statement[0]]: Extract<Statement, { 0: TSexpOpcode }>;
129};
130export type ExpressionSexpOpcode = TupleExpression[0];
131export type ExpressionSexpOpcodeMap = {
132 [TSexpOpcode in TupleExpression[0]]: Extract<TupleExpression, { 0: TSexpOpcode }>;
133};
134
135export interface SexpOpcodeMap extends ExpressionSexpOpcodeMap, StatementSexpOpcodeMap {}
136export type SexpOpcode = keyof SexpOpcodeMap;
137
138export namespace Core {
139 export type Expression = Expressions.Expression;
140
141 export type CallArgs = [Params, Hash];
142 export type Path = [string, ...string[]];
143 export type ConcatParams = PresentArray<Expression>;
144 export type Params = Option<ConcatParams>;
145 export type Hash = Option<[PresentArray<string>, PresentArray<Expression>]>;
146 export type Blocks = Option<[string[], SerializedInlineBlock[]]>;
147 export type Args = [Params, Hash];
148 export type NamedBlock = [string, SerializedInlineBlock];
149 export type EvalInfo = number[];
150 export type ElementParameters = Option<PresentArray<ElementParameter>>;
151
152 export type Syntax = Path | Params | ConcatParams | Hash | Blocks | Args | EvalInfo;
153}
154
155export type CoreSyntax = Core.Syntax;
156
157export namespace Expressions {
158 export type Path = Core.Path;
159 export type Params = Core.Params;
160 export type Hash = Core.Hash;
161
162 export type GetSymbol = [SexpOpcodes.GetSymbol, number];
163 export type GetTemplateSymbol = [SexpOpcodes.GetTemplateSymbol, number];
164 export type GetStrictFree = [SexpOpcodes.GetStrictFree, number];
165 export type GetFreeAsComponentOrHelperHeadOrThisFallback = [
166 SexpOpcodes.GetFreeAsComponentOrHelperHeadOrThisFallback,
167 number
168 ];
169 export type GetFreeAsComponentOrHelperHead = [SexpOpcodes.GetFreeAsComponentOrHelperHead, number];
170 export type GetFreeAsHelperHeadOrThisFallback = [
171 SexpOpcodes.GetFreeAsHelperHeadOrThisFallback,
172 number
173 ];
174 export type GetFreeAsDeprecatedHelperHeadOrThisFallback = [
175 SexpOpcodes.GetFreeAsDeprecatedHelperHeadOrThisFallback,
176 number
177 ];
178 export type GetFreeAsHelperHead = [SexpOpcodes.GetFreeAsHelperHead, number];
179 export type GetFreeAsModifierHead = [SexpOpcodes.GetFreeAsModifierHead, number];
180 export type GetFreeAsComponentHead = [SexpOpcodes.GetFreeAsComponentHead, number];
181
182 export type GetContextualFree =
183 | GetFreeAsComponentOrHelperHeadOrThisFallback
184 | GetFreeAsComponentOrHelperHead
185 | GetFreeAsHelperHeadOrThisFallback
186 | GetFreeAsDeprecatedHelperHeadOrThisFallback
187 | GetFreeAsHelperHead
188 | GetFreeAsModifierHead
189 | GetFreeAsComponentHead;
190 export type GetFree = GetStrictFree | GetContextualFree;
191 export type GetVar = GetSymbol | GetTemplateSymbol | GetFree;
192
193 export type GetPathSymbol = [SexpOpcodes.GetSymbol, number, Path];
194 export type GetPathTemplateSymbol = [SexpOpcodes.GetTemplateSymbol, number, Path];
195 export type GetPathStrictFree = [SexpOpcodes.GetStrictFree, number, Path];
196 export type GetPathFreeAsComponentOrHelperHeadOrThisFallback = [
197 SexpOpcodes.GetFreeAsComponentOrHelperHeadOrThisFallback,
198 number,
199 Path
200 ];
201 export type GetPathFreeAsComponentOrHelperHead = [
202 SexpOpcodes.GetFreeAsComponentOrHelperHead,
203 number,
204 Path
205 ];
206 export type GetPathFreeAsHelperHeadOrThisFallback = [
207 SexpOpcodes.GetFreeAsHelperHeadOrThisFallback,
208 number,
209 Path
210 ];
211 export type GetPathFreeAsDeprecatedHelperHeadOrThisFallback = [
212 SexpOpcodes.GetFreeAsDeprecatedHelperHeadOrThisFallback,
213 number,
214 Path
215 ];
216 export type GetPathFreeAsHelperHead = [SexpOpcodes.GetFreeAsHelperHead, number, Path];
217 export type GetPathFreeAsModifierHead = [SexpOpcodes.GetFreeAsModifierHead, number, Path];
218 export type GetPathFreeAsComponentHead = [SexpOpcodes.GetFreeAsComponentHead, number, Path];
219
220 export type GetPathContextualFree =
221 | GetPathFreeAsComponentOrHelperHeadOrThisFallback
222 | GetPathFreeAsComponentOrHelperHead
223 | GetPathFreeAsHelperHeadOrThisFallback
224 | GetPathFreeAsDeprecatedHelperHeadOrThisFallback
225 | GetPathFreeAsHelperHead
226 | GetPathFreeAsModifierHead
227 | GetPathFreeAsComponentHead;
228 export type GetPathFree = GetPathStrictFree | GetPathContextualFree;
229 export type GetPath = GetPathSymbol | GetPathTemplateSymbol | GetPathFree;
230
231 export type Get = GetVar | GetPath;
232
233 export type StringValue = string;
234 export type NumberValue = number;
235 export type BooleanValue = boolean;
236 export type NullValue = null;
237 export type Value = StringValue | NumberValue | BooleanValue | NullValue;
238 export type Undefined = [SexpOpcodes.Undefined];
239
240 export type TupleExpression =
241 | Get
242 | GetDynamicVar
243 | Concat
244 | HasBlock
245 | HasBlockParams
246 | Curry
247 | Helper
248 | Undefined
249 | IfInline
250 | Not
251 | Log;
252
253 // TODO get rid of undefined, which is just here to allow trailing undefined in attrs
254 // it would be better to handle that as an over-the-wire encoding concern
255 export type Expression = TupleExpression | Value | undefined;
256
257 export type Concat = [SexpOpcodes.Concat, Core.ConcatParams];
258 export type Helper = [SexpOpcodes.Call, Expression, Option<Params>, Hash];
259 export type HasBlock = [SexpOpcodes.HasBlock, Expression];
260 export type HasBlockParams = [SexpOpcodes.HasBlockParams, Expression];
261 export type Curry = [SexpOpcodes.Curry, Expression, CurriedType, Params, Hash];
262
263 export type IfInline = [
264 op: SexpOpcodes.IfInline,
265 condition: Expression,
266 truthyValue: Expression,
267 falsyValue?: Option<Expression>
268 ];
269
270 export type Not = [op: SexpOpcodes.Not, value: Expression];
271
272 export type GetDynamicVar = [op: SexpOpcodes.GetDynamicVar, value: Expression];
273
274 export type Log = [op: SexpOpcodes.Log, positional: Params];
275}
276
277export type Expression = Expressions.Expression;
278export type Get = Expressions.GetVar;
279
280export type TupleExpression = Expressions.TupleExpression;
281
282export const enum WellKnownAttrName {
283 class = 0,
284 id = 1,
285 value = 2,
286 name = 3,
287 type = 4,
288 style = 5,
289 href = 6,
290}
291
292export const enum WellKnownTagName {
293 div = 0,
294 span = 1,
295 p = 2,
296 a = 3,
297}
298
299export namespace Statements {
300 export type Expression = Expressions.Expression | undefined;
301 export type Params = Core.Params;
302 export type Hash = Core.Hash;
303 export type Blocks = Core.Blocks;
304 export type Path = Core.Path;
305
306 export type Append = [SexpOpcodes.Append, Expression];
307 export type TrustingAppend = [SexpOpcodes.TrustingAppend, Expression];
308 export type Comment = [SexpOpcodes.Comment, string];
309 export type Modifier = [SexpOpcodes.Modifier, Expression, Params, Hash];
310 export type Block = [SexpOpcodes.Block, Expression, Params, Hash, Blocks];
311 export type Component = [
312 op: SexpOpcodes.Component,
313 tag: Expression,
314 parameters: Core.ElementParameters,
315 args: Hash,
316 blocks: Blocks
317 ];
318 export type OpenElement = [SexpOpcodes.OpenElement, string | WellKnownTagName];
319 export type OpenElementWithSplat = [SexpOpcodes.OpenElementWithSplat, string | WellKnownTagName];
320 export type FlushElement = [SexpOpcodes.FlushElement];
321 export type CloseElement = [SexpOpcodes.CloseElement];
322 export type StaticAttr = [
323 SexpOpcodes.StaticAttr,
324 string | WellKnownAttrName,
325 Expression,
326 string?
327 ];
328 export type StaticComponentAttr = [
329 SexpOpcodes.StaticComponentAttr,
330 string | WellKnownAttrName,
331 Expression,
332 string?
333 ];
334
335 export type AnyStaticAttr = StaticAttr | StaticComponentAttr;
336
337 export type AttrSplat = [SexpOpcodes.AttrSplat, YieldTo];
338 export type Yield = [SexpOpcodes.Yield, YieldTo, Option<Params>];
339 export type DynamicArg = [SexpOpcodes.DynamicArg, string, Expression];
340 export type StaticArg = [SexpOpcodes.StaticArg, string, Expression];
341
342 export type DynamicAttr = [
343 SexpOpcodes.DynamicAttr,
344 string | WellKnownAttrName,
345 Expression,
346 string?
347 ];
348 export type ComponentAttr = [
349 SexpOpcodes.ComponentAttr,
350 string | WellKnownAttrName,
351 Expression,
352 string?
353 ];
354 export type TrustingDynamicAttr = [
355 SexpOpcodes.TrustingDynamicAttr,
356 string | WellKnownAttrName,
357 Expression,
358 string?
359 ];
360 export type TrustingComponentAttr = [
361 SexpOpcodes.TrustingComponentAttr,
362 string | WellKnownAttrName,
363 Expression,
364 string?
365 ];
366
367 export type AnyDynamicAttr =
368 | DynamicAttr
369 | ComponentAttr
370 | TrustingDynamicAttr
371 | TrustingComponentAttr;
372
373 export type Debugger = [SexpOpcodes.Debugger, Core.EvalInfo];
374 export type InElement = [
375 op: SexpOpcodes.InElement,
376 block: SerializedInlineBlock,
377 guid: string,
378 destination: Expression,
379 insertBefore?: Expression
380 ];
381
382 export type If = [
383 op: SexpOpcodes.If,
384 condition: Expression,
385 block: SerializedInlineBlock,
386 inverse: Option<SerializedInlineBlock>
387 ];
388
389 export type Each = [
390 op: SexpOpcodes.Each,
391 condition: Expression,
392 key: Option<Expression>,
393 block: SerializedInlineBlock,
394 inverse: Option<SerializedInlineBlock>
395 ];
396
397 export type With = [
398 op: SexpOpcodes.With,
399 value: Expression,
400 block: SerializedInlineBlock,
401 inverse: Option<SerializedInlineBlock>
402 ];
403
404 export type Let = [op: SexpOpcodes.Let, positional: Core.Params, block: SerializedInlineBlock];
405
406 export type WithDynamicVars = [
407 op: SexpOpcodes.WithDynamicVars,
408 args: Core.Hash,
409 block: SerializedInlineBlock
410 ];
411
412 export type InvokeComponent = [
413 op: SexpOpcodes.InvokeComponent,
414 definition: Expression,
415 positional: Core.Params,
416 named: Core.Hash,
417 blocks: Blocks | null
418 ];
419
420 /**
421 * A Handlebars statement
422 */
423 export type Statement =
424 | Append
425 | TrustingAppend
426 | Comment
427 | Modifier
428 | Block
429 | Component
430 | OpenElement
431 | OpenElementWithSplat
432 | FlushElement
433 | CloseElement
434 | Attribute
435 | AttrSplat
436 | Yield
437 | StaticArg
438 | DynamicArg
439 | Debugger
440 | InElement
441 | If
442 | Each
443 | With
444 | Let
445 | WithDynamicVars
446 | InvokeComponent;
447
448 export type Attribute =
449 | StaticAttr
450 | StaticComponentAttr
451 | DynamicAttr
452 | TrustingDynamicAttr
453 | ComponentAttr
454 | TrustingComponentAttr;
455
456 export type ComponentFeature = Modifier | AttrSplat;
457 export type Argument = StaticArg | DynamicArg;
458
459 export type ElementParameter = Attribute | Argument | ComponentFeature;
460}
461
462/** A Handlebars statement */
463export type Statement = Statements.Statement;
464export type Attribute = Statements.Attribute;
465export type Argument = Statements.Argument;
466export type ElementParameter = Statements.ElementParameter;
467
468export type SexpSyntax = Statement | TupleExpression;
469// TODO this undefined is related to the other TODO in this file
470export type Syntax = SexpSyntax | Expressions.Value | undefined;
471
472export type SyntaxWithInternal =
473 | Syntax
474 | CoreSyntax
475 | SerializedTemplateBlock
476 | Core.CallArgs
477 | Core.NamedBlock
478 | Core.ElementParameters;
479
480/**
481 * A JSON object that the Block was serialized into.
482 */
483export type SerializedBlock = [statements: Statements.Statement[]];
484
485export type SerializedInlineBlock = [statements: Statements.Statement[], parameters: number[]];
486
487/**
488 * A JSON object that the compiled TemplateBlock was serialized into.
489 */
490export type SerializedTemplateBlock = [
491 // statements
492 Statements.Statement[],
493 // symbols
494 string[],
495 // hasEval
496 boolean,
497 // upvars
498 string[]
499];
500
501/**
502 * A JSON object that the compiled Template was serialized into.
503 */
504export interface SerializedTemplate {
505 block: SerializedTemplateBlock;
506 id?: Option<string>;
507 moduleName: string;
508}
509
510/**
511 * A string of JSON containing a SerializedTemplateBlock
512 */
513export type SerializedTemplateBlockJSON = string;
514
515/**
516 * A JSON object containing the SerializedTemplateBlock as JSON and TemplateMeta.
517 */
518export interface SerializedTemplateWithLazyBlock {
519 id?: Option<string>;
520 block: SerializedTemplateBlockJSON;
521 moduleName: string;
522 scope: (() => unknown[]) | undefined | null;
523 isStrictMode: boolean;
524}
525
526/**
527 * A string of Javascript containing a SerializedTemplateWithLazyBlock to be
528 * concatenated into a Javascript module.
529 */
530export type TemplateJavascript = string;
531
\No newline at end of file