@firsthandjs/compiler 0.9.0 → 0.10.0
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/dist/attributes.d.ts +13 -0
- package/dist/attributes.d.ts.map +1 -0
- package/dist/chunk-JEIWCE46.js +1998 -0
- package/dist/components.d.ts +25 -0
- package/dist/components.d.ts.map +1 -0
- package/dist/guarded.d.ts +22 -0
- package/dist/guarded.d.ts.map +1 -0
- package/dist/html.d.ts +12 -0
- package/dist/html.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/jsx.d.ts +39 -0
- package/dist/jsx.d.ts.map +1 -0
- package/dist/lists.d.ts +24 -0
- package/dist/lists.d.ts.map +1 -0
- package/dist/marks.d.ts +31 -0
- package/dist/marks.d.ts.map +1 -0
- package/dist/markup.d.ts +27 -0
- package/dist/markup.d.ts.map +1 -0
- package/dist/nodes.d.ts +55 -0
- package/dist/nodes.d.ts.map +1 -0
- package/dist/options.d.ts +48 -0
- package/dist/options.d.ts.map +1 -0
- package/dist/plugin.d.ts +12 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/positions.d.ts +50 -0
- package/dist/positions.d.ts.map +1 -0
- package/dist/props.d.ts +25 -0
- package/dist/props.d.ts.map +1 -0
- package/dist/runs.d.ts +69 -0
- package/dist/runs.d.ts.map +1 -0
- package/dist/site.d.ts +12 -0
- package/dist/site.d.ts.map +1 -0
- package/dist/state.d.ts +84 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/strict.d.ts +72 -0
- package/dist/strict.d.ts.map +1 -0
- package/dist/template.d.ts +11 -0
- package/dist/template.d.ts.map +1 -0
- package/dist/transform.d.ts +14 -86
- package/dist/transform.d.ts.map +1 -1
- package/dist/vite.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-ACKKPAGI.js +0 -1828
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a `component(...)` call gains on the way through (ADR-0004).
|
|
3
|
+
*
|
|
4
|
+
* A stable build id, a display name, props rewritten into live reads, and —
|
|
5
|
+
* under the `devtools` option only — a label on each cell the module creates.
|
|
6
|
+
*/
|
|
7
|
+
import type { NodePath } from '@babel/traverse';
|
|
8
|
+
import * as t from '@babel/types';
|
|
9
|
+
import type { FirsthandPluginOptions } from './options.js';
|
|
10
|
+
import { type State } from './state.js';
|
|
11
|
+
/**
|
|
12
|
+
* Gives every `component(...)` call a stable build id and a display name, and
|
|
13
|
+
* rejects props destructuring.
|
|
14
|
+
*/
|
|
15
|
+
export declare function annotateComponent(path: NodePath<t.CallExpression>, state: State, options: FirsthandPluginOptions): void;
|
|
16
|
+
/**
|
|
17
|
+
* Labels `const count = signal(0)` with `count` and where it was written.
|
|
18
|
+
*
|
|
19
|
+
* Emitted only under the `devtools` option, so a production build is
|
|
20
|
+
* byte-identical to one compiled without it. The label is wrapped around the
|
|
21
|
+
* call rather than passed into it: `signal` keeps its signature, and a cell
|
|
22
|
+
* created any other way is simply unnamed rather than special.
|
|
23
|
+
*/
|
|
24
|
+
export declare function nameCell(path: NodePath<t.VariableDeclarator>, state: State): void;
|
|
25
|
+
//# sourceMappingURL=components.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"components.d.ts","sourceRoot":"","sources":["../src/components.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAIlC,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAM3D,OAAO,EAAW,KAAK,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjD;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,EAChC,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,sBAAsB,GAC9B,IAAI,CA2BN;AASD;;;;;;;GAOG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,kBAAkB,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,CA2BjF"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A write a run performs, guarded by what it last put there.
|
|
3
|
+
*
|
|
4
|
+
* Its own module because two callers need it and neither should import the
|
|
5
|
+
* other: an attribute is written this way, and so is a child.
|
|
6
|
+
*/
|
|
7
|
+
import * as t from '@babel/types';
|
|
8
|
+
import { type Build, type State } from './state.js';
|
|
9
|
+
/**
|
|
10
|
+
* A write the run performs, guarded by what it last put there.
|
|
11
|
+
*
|
|
12
|
+
* ```js
|
|
13
|
+
* const _w$1 = _$site(_store, 3), _x$1 = u.kind;
|
|
14
|
+
* if (_w$1.last !== _x$1) { _w$1.last = _x$1; _$applyProp(_el$, "class", _x$1); }
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* The comparison is against a remembered value rather than against the DOM:
|
|
18
|
+
* reading an attribute or a text node back costs more than writing it, which
|
|
19
|
+
* is the one thing measuring this changed my mind about.
|
|
20
|
+
*/
|
|
21
|
+
export declare function guardedWrite(build: Build, state: State, value: t.Expression, write: (held: t.Identifier) => t.Expression): void;
|
|
22
|
+
//# sourceMappingURL=guarded.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"guarded.d.ts","sourceRoot":"","sources":["../src/guarded.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAIlC,OAAO,EAAqB,KAAK,KAAK,EAAmB,KAAK,KAAK,EAAE,MAAM,YAAY,CAAC;AAExF;;;;;;;;;;;GAWG;AACH,wBAAgB,YAAY,CAC1B,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,KAAK,EACZ,KAAK,EAAE,CAAC,CAAC,UAAU,EACnB,KAAK,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,UAAU,GAC1C,IAAI,CA8BN"}
|
package/dist/html.d.ts
CHANGED
|
@@ -16,4 +16,16 @@ export declare function escapeText(value: string): string;
|
|
|
16
16
|
export declare function escapeAttribute(value: string): string;
|
|
17
17
|
/** `onPointerDown` -> `pointerdown`. */
|
|
18
18
|
export declare function eventName(attribute: string): string;
|
|
19
|
+
/**
|
|
20
|
+
* Whether an attribute name is a listener.
|
|
21
|
+
*
|
|
22
|
+
* `onClick` and `on:sl-change` are both listeners; `once` and `onwards` are
|
|
23
|
+
* not, which is what the third character decides — a capital or a colon after
|
|
24
|
+
* `on` is the only thing that makes the rest a type name.
|
|
25
|
+
*
|
|
26
|
+
* One definition rather than two, because the browser path and the server path
|
|
27
|
+
* both need it and have to agree: a name the server skips and the browser
|
|
28
|
+
* attaches would be a listener nobody could reach.
|
|
29
|
+
*/
|
|
30
|
+
export declare function isEventName(name: string): boolean;
|
|
19
31
|
//# sourceMappingURL=html.d.ts.map
|
package/dist/html.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../src/html.ts"],"names":[],"mappings":"AAAA,wEAAwE;AAExE,wCAAwC;AACxC,eAAO,MAAM,aAAa,aAexB,CAAC;AAEH,2EAA2E;AAC3E,eAAO,MAAM,kBAAkB,aAa7B,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,cAAc,aAWzB,CAAC;AAEH,mEAAmE;AACnE,eAAO,MAAM,YAAY,aAsBvB,CAAC;AAEH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wCAAwC;AACxC,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEnD"}
|
|
1
|
+
{"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../src/html.ts"],"names":[],"mappings":"AAAA,wEAAwE;AAExE,wCAAwC;AACxC,eAAO,MAAM,aAAa,aAexB,CAAC;AAEH,2EAA2E;AAC3E,eAAO,MAAM,kBAAkB,aAa7B,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,cAAc,aAWzB,CAAC;AAEH,mEAAmE;AACnE,eAAO,MAAM,YAAY,aAsBvB,CAAC;AAEH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wCAAwC;AACxC,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD"}
|
package/dist/index.js
CHANGED
package/dist/jsx.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where a JSX node goes: a component call, a server's markup, or a template.
|
|
3
|
+
*
|
|
4
|
+
* `compileNode` is the fork, and the two branches below it are the whole of
|
|
5
|
+
* what a component needs — its props as accessors, and the machinery that lets
|
|
6
|
+
* a run keep the child it made last time.
|
|
7
|
+
*/
|
|
8
|
+
import type { NodePath } from '@babel/traverse';
|
|
9
|
+
import * as t from '@babel/types';
|
|
10
|
+
import { type State } from './state.js';
|
|
11
|
+
export declare function compileNode(path: NodePath<t.JSXElement | t.JSXFragment>, state: State): t.Expression;
|
|
12
|
+
/**
|
|
13
|
+
* Compiles the children of a fragment, or of a component that takes children.
|
|
14
|
+
*
|
|
15
|
+
* A dynamic child becomes a `part(...)`, not a bare thunk. An array has no
|
|
16
|
+
* parent element, so its dynamic children cannot be bound where they are
|
|
17
|
+
* written — and deferring them to insertion time would evaluate them under
|
|
18
|
+
* whoever inserts the array, which loses the scope they belong to and does not
|
|
19
|
+
* make them reactive at all. `part` carries that scope along with an anchor,
|
|
20
|
+
* and the runtime binds it once the array is in the DOM.
|
|
21
|
+
*/
|
|
22
|
+
export declare function compileChildren(children: t.JSXElement['children'], state: State, kept?: Kept): t.Expression[];
|
|
23
|
+
/**
|
|
24
|
+
* How a kept child is told what its run currently says.
|
|
25
|
+
*
|
|
26
|
+
* A component inside a run is made once, so an expression it is given cannot be
|
|
27
|
+
* left as a binding of the run that made it — the second run has its own, and
|
|
28
|
+
* the child would go on reading the first for ever.
|
|
29
|
+
*/
|
|
30
|
+
type Kept = {
|
|
31
|
+
/** Whether an expression names anything belonging to the run. */
|
|
32
|
+
depends(value: t.Expression): boolean;
|
|
33
|
+
/** The expression, read through a cell the run writes on every run. */
|
|
34
|
+
cell(value: t.Expression): t.Expression;
|
|
35
|
+
/** A value, written to a cell on every run and read from it. */
|
|
36
|
+
value(value: t.Expression): t.Expression;
|
|
37
|
+
};
|
|
38
|
+
export {};
|
|
39
|
+
//# sourceMappingURL=jsx.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jsx.d.ts","sourceRoot":"","sources":["../src/jsx.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAqBlC,OAAO,EAA4B,KAAK,KAAK,EAAE,MAAM,YAAY,CAAC;AAIlE,wBAAgB,WAAW,CACzB,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,WAAW,CAAC,EAC5C,KAAK,EAAE,KAAK,GACX,CAAC,CAAC,UAAU,CASd;AA6ND;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,EAClC,KAAK,EAAE,KAAK,EACZ,IAAI,CAAC,EAAE,IAAI,GACV,CAAC,CAAC,UAAU,EAAE,CAuBhB;AAED;;;;;;GAMG;AACH,KAAK,IAAI,GAAG;IACV,iEAAiE;IACjE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,UAAU,GAAG,OAAO,CAAC;IACtC,uEAAuE;IACvE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC;IACxC,gEAAgE;IAChE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC;CAC1C,CAAC"}
|
package/dist/lists.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `items.map(row => <Row key={row.id} />)` becomes a keyed list part.
|
|
3
|
+
*
|
|
4
|
+
* A rewrite rather than a compilation: what comes out is still JSX, and the
|
|
5
|
+
* passes after this one compile it without knowing a list was involved. The
|
|
6
|
+
* mark `LIST_CALL` is how they find out where it matters.
|
|
7
|
+
*/
|
|
8
|
+
import type { NodePath } from '@babel/traverse';
|
|
9
|
+
import * as t from '@babel/types';
|
|
10
|
+
import { type State } from './state.js';
|
|
11
|
+
/**
|
|
12
|
+
* Rewrites `items.map(item => <Row key={item.id} .../>)` into a keyed list part.
|
|
13
|
+
*
|
|
14
|
+
* The callback's item parameter becomes a reactive cell and every reference to
|
|
15
|
+
* it becomes a live read, so a row whose data changes updates in place instead
|
|
16
|
+
* of being re-created. The key expression is extracted first, because it is
|
|
17
|
+
* computed from the raw item, once per reconcile.
|
|
18
|
+
*
|
|
19
|
+
* A `.map()` without a `key` stays an ordinary array child: it is reconciled by
|
|
20
|
+
* node identity, which for freshly created nodes means "replace". That is the
|
|
21
|
+
* documented cost of leaving the key out.
|
|
22
|
+
*/
|
|
23
|
+
export declare function rewriteKeyedMaps(path: NodePath<t.JSXElement | t.JSXFragment>, state: State): void;
|
|
24
|
+
//# sourceMappingURL=lists.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lists.d.ts","sourceRoot":"","sources":["../src/lists.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAIlC,OAAO,EAAW,KAAK,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjD;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,CASjG"}
|
package/dist/marks.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The marks the compiler leaves on nodes it wrote.
|
|
3
|
+
*
|
|
4
|
+
* Three symbols and the predicates that read them. A symbol rather than a
|
|
5
|
+
* property name because these travel on Babel nodes, which are shared with
|
|
6
|
+
* every other plugin in the pipeline: a name could collide, and a mark that
|
|
7
|
+
* collided would silently change what the compiler decides about a node.
|
|
8
|
+
*/
|
|
9
|
+
import * as t from '@babel/types';
|
|
10
|
+
/**
|
|
11
|
+
* Marks an arrow the compiler wrote for a child slot.
|
|
12
|
+
*
|
|
13
|
+
* Whatever sits directly in one is already inside a reactive scope, so a view
|
|
14
|
+
* function there can be called where it stands instead of being wrapped in a
|
|
15
|
+
* part of its own.
|
|
16
|
+
*/
|
|
17
|
+
export declare const CHILD_THUNK: unique symbol;
|
|
18
|
+
/**
|
|
19
|
+
* Marks a wrapper the compiler wrote, which is not a scope of anyone's.
|
|
20
|
+
*
|
|
21
|
+
* A template compiles to an immediately invoked arrow, and that arrow is a
|
|
22
|
+
* function — so walking up from markup inside it would stop there and lose the
|
|
23
|
+
* run it belongs to. It is machinery, not a boundary, and is walked through.
|
|
24
|
+
*/
|
|
25
|
+
export declare const GENERATED: unique symbol;
|
|
26
|
+
export declare function generated(arrow: t.ArrowFunctionExpression): t.ArrowFunctionExpression;
|
|
27
|
+
/** Marks a call the map rewrite produced, so it is not wrapped in a thunk. */
|
|
28
|
+
export declare const LIST_CALL: unique symbol;
|
|
29
|
+
/** Whether an expression is the keyed-list call `rewriteKeyedMaps` produced. */
|
|
30
|
+
export declare function isKeyedList(node: t.Node): boolean;
|
|
31
|
+
//# sourceMappingURL=marks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"marks.d.ts","sourceRoot":"","sources":["../src/marks.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAElC;;;;;;GAMG;AACH,eAAO,MAAM,WAAW,eAAiC,CAAC;AAE1D;;;;;;GAMG;AACH,eAAO,MAAM,SAAS,eAAgC,CAAC;AAEvD,wBAAgB,SAAS,CAAC,KAAK,EAAE,CAAC,CAAC,uBAAuB,GAAG,CAAC,CAAC,uBAAuB,CAGrF;AAED,8EAA8E;AAC9E,eAAO,MAAM,SAAS,eAA2B,CAAC;AAElD,gFAAgF;AAChF,wBAAgB,WAAW,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,GAAG,OAAO,CAEjD"}
|
package/dist/markup.d.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A host element, for a server render: the static chunks and the values
|
|
3
|
+
* between them.
|
|
4
|
+
*
|
|
5
|
+
* The structure has to be the structure the browser would have built, node for
|
|
6
|
+
* node, or hydration walks into the wrong place. Every decision here mirrors
|
|
7
|
+
* one in `template.ts`.
|
|
8
|
+
*/
|
|
9
|
+
import type { NodePath } from '@babel/traverse';
|
|
10
|
+
import * as t from '@babel/types';
|
|
11
|
+
import { type State } from './state.js';
|
|
12
|
+
/**
|
|
13
|
+
* Compiles an element to the markup a server sends.
|
|
14
|
+
*
|
|
15
|
+
* The structure has to be **the same structure** the browser would have built,
|
|
16
|
+
* node for node, or hydration walks into the wrong place: the client navigates
|
|
17
|
+
* a template by `firstChild` and `nextSibling`, and a comment the server left
|
|
18
|
+
* out is a step the client takes anyway. So the decisions here mirror
|
|
19
|
+
* `emitChildren` exactly, including the marker comment after a dynamic child
|
|
20
|
+
* that is not the last one.
|
|
21
|
+
*
|
|
22
|
+
* That mirroring is a promise between two files, which is the kind of promise
|
|
23
|
+
* that rots. It is held by `packages/server/test/parity.test.tsx`, which
|
|
24
|
+
* renders every shape both ways and compares what comes out.
|
|
25
|
+
*/
|
|
26
|
+
export declare function compileMarkup(path: NodePath<t.JSXElement>, state: State): t.Expression;
|
|
27
|
+
//# sourceMappingURL=markup.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markup.d.ts","sourceRoot":"","sources":["../src/markup.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAoBlC,OAAO,EAAW,KAAK,KAAK,EAAE,MAAM,YAAY,CAAC;AAoBjD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC,CAAC,UAAU,CAatF"}
|
package/dist/nodes.d.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a node is, asked of the node.
|
|
3
|
+
*
|
|
4
|
+
* Small, total questions about a Babel AST: is this tag a component, is this
|
|
5
|
+
* value static, what is this attribute called. Nothing here reads the
|
|
6
|
+
* compiler's state or emits anything, which is what makes them safe to call
|
|
7
|
+
* from any pass — and why they are in one module rather than repeated in
|
|
8
|
+
* three.
|
|
9
|
+
*/
|
|
10
|
+
import type { NodePath } from '@babel/traverse';
|
|
11
|
+
import * as t from '@babel/types';
|
|
12
|
+
export declare function isComponentTag(node: t.JSXElement): boolean;
|
|
13
|
+
export declare function tagExpression(name: t.JSXIdentifier | t.JSXMemberExpression): t.Expression;
|
|
14
|
+
/**
|
|
15
|
+
* Whether evaluating an expression is something nobody could notice.
|
|
16
|
+
*
|
|
17
|
+
* Names, member chains, literals and the operators over them: reading them
|
|
18
|
+
* early is the same as reading them late. A call is not — it may do anything,
|
|
19
|
+
* including not returning — and neither is anything that writes, waits or
|
|
20
|
+
* constructs. Deliberately conservative: a shape not listed here is treated as
|
|
21
|
+
* observable, which costs an accessor and never a wrong answer.
|
|
22
|
+
*/
|
|
23
|
+
export declare function isPure(node: t.Expression): boolean;
|
|
24
|
+
export declare function propertyKey(name: string): t.Identifier | t.StringLiteral;
|
|
25
|
+
export declare function attributeName(attribute: t.JSXAttribute): string;
|
|
26
|
+
export declare function attributeValue(attribute: t.JSXAttribute): t.Expression | null;
|
|
27
|
+
export declare function isStaticValue(value: t.Expression): boolean;
|
|
28
|
+
export declare function canInlineAttribute(name: string): boolean;
|
|
29
|
+
export declare function isFirsthandImport(binding: {
|
|
30
|
+
path: NodePath;
|
|
31
|
+
}): boolean;
|
|
32
|
+
export declare function declaredName(path: NodePath<t.CallExpression>): string;
|
|
33
|
+
export type ChildEntry = {
|
|
34
|
+
kind: 'text' | 'element' | 'dynamic' | 'list';
|
|
35
|
+
text?: string;
|
|
36
|
+
element?: t.JSXElement;
|
|
37
|
+
expression?: t.Expression;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* Groups JSX children into DOM nodes.
|
|
41
|
+
*
|
|
42
|
+
* Adjacent text and static expressions merge into one text node, which is what
|
|
43
|
+
* the HTML parser will produce, so child indices stay correct.
|
|
44
|
+
*/
|
|
45
|
+
export declare function planChildren(children: t.JSXElement['children']): ChildEntry[];
|
|
46
|
+
/**
|
|
47
|
+
* The text a static attribute value stands for.
|
|
48
|
+
*
|
|
49
|
+
* `false` and `null` are absences rather than values — an attribute written
|
|
50
|
+
* with either is not written at all — so they are `null` here and the caller
|
|
51
|
+
* omits the attribute. Both paths need this and have to agree: a value the
|
|
52
|
+
* server writes and the browser omits is a hydration mismatch.
|
|
53
|
+
*/
|
|
54
|
+
export declare function staticLiteral(value: t.Expression): string | null;
|
|
55
|
+
//# sourceMappingURL=nodes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nodes.d.ts","sourceRoot":"","sources":["../src/nodes.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAQlC,wBAAgB,cAAc,CAAC,IAAI,EAAE,CAAC,CAAC,UAAU,GAAG,OAAO,CAS1D;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC,mBAAmB,GAAG,CAAC,CAAC,UAAU,CAKzF;AAED;;;;;;;;GAQG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,UAAU,GAAG,OAAO,CAWlD;AAuED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,aAAa,CAExE;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,CAAC,CAAC,YAAY,GAAG,MAAM,CAG/D;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,CAAC,CAAC,YAAY,GAAG,CAAC,CAAC,UAAU,GAAG,IAAI,CAc7E;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,CAAC,CAAC,UAAU,GAAG,OAAO,CAO1D;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAOxD;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,GAAG,OAAO,CAOtE;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,MAAM,CAMrE;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,CAAC;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC;IACvB,UAAU,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC;CAC3B,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,UAAU,EAAE,CAsC7E;AAqBD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,CAAC,CAAC,UAAU,GAAG,MAAM,GAAG,IAAI,CAWhE"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/** The options the Babel plugin takes. */
|
|
2
|
+
export type FirsthandPluginOptions = {
|
|
3
|
+
/** Package name used when hashing stable component ids (ADR-0004). */
|
|
4
|
+
packageName?: string;
|
|
5
|
+
/**
|
|
6
|
+
* Refuse to compile a value that is read once in a setup and then kept.
|
|
7
|
+
*
|
|
8
|
+
* **On by default.** The rule only sees declarations whose initialiser is
|
|
9
|
+
* nothing but a read, which is the shape that is almost always a mistake;
|
|
10
|
+
* anything containing a call is left alone. `false` turns it off for a
|
|
11
|
+
* codebase that has such a read on purpose and would rather not mark it with
|
|
12
|
+
* `snapshot()` — see `checkKeptReads` (ADR-0019).
|
|
13
|
+
*/
|
|
14
|
+
strictReactivity?: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Name the cells a module creates, for devtools.
|
|
17
|
+
*
|
|
18
|
+
* A runtime cannot see that `const count = signal(0)` is called `count`, and
|
|
19
|
+
* `new Error().stack` reports a position in the *compiled* module — the
|
|
20
|
+
* browser does not apply source maps to `error.stack`, so the line it names
|
|
21
|
+
* is not the line that was written. The compiler knows both, so it says so.
|
|
22
|
+
*
|
|
23
|
+
* Off by default and turned on by the Vite plugin while serving: a
|
|
24
|
+
* production build emits nothing.
|
|
25
|
+
*/
|
|
26
|
+
devtools?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Compile for a server render.
|
|
29
|
+
*
|
|
30
|
+
* The same source, emitted against `@firsthandjs/server/internal` instead of
|
|
31
|
+
* `@firsthandjs/dom/internal`: markup is built as a string rather than as
|
|
32
|
+
* nodes, and the things a server cannot do — listeners, refs, retained
|
|
33
|
+
* sites — are not emitted at all.
|
|
34
|
+
*
|
|
35
|
+
* The Vite plugin sets this from the bundler's own `ssr` flag, so an
|
|
36
|
+
* application configures nothing.
|
|
37
|
+
*/
|
|
38
|
+
ssr?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Emit navigation that can walk server markup.
|
|
41
|
+
*
|
|
42
|
+
* An application that hydrates needs it; one that does not should leave it
|
|
43
|
+
* off, because it turns two property reads per dynamic position into two
|
|
44
|
+
* calls. The Vite plugin sets it for a project that has a server build.
|
|
45
|
+
*/
|
|
46
|
+
hydratable?: boolean;
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=options.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"options.d.ts","sourceRoot":"","sources":["../src/options.ts"],"names":[],"mappings":"AAAA,0CAA0C;AAE1C,MAAM,MAAM,sBAAsB,GAAG;IACnC,sEAAsE;IACtE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;;OAQG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B;;;;;;;;;;OAUG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;;;;;OAUG;IACH,GAAG,CAAC,EAAE,OAAO,CAAC;IACd;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC"}
|
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Babel plugin: the visitors, and the order the passes run in.
|
|
3
|
+
*
|
|
4
|
+
* Two passes run on `Program` before anything is compiled, because both answer
|
|
5
|
+
* questions that must not depend on the order Babel walks in. Everything the
|
|
6
|
+
* module accumulates — templates, imports, view registrations — is written
|
|
7
|
+
* back out on the way past `Program` again.
|
|
8
|
+
*/
|
|
9
|
+
import type { PluginObject } from '@babel/core';
|
|
10
|
+
import type { FirsthandPluginOptions } from './options.js';
|
|
11
|
+
export default function firsthandPlugin(_api: unknown, options?: FirsthandPluginOptions): PluginObject;
|
|
12
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAchD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC;AAQ3D,MAAM,CAAC,OAAO,UAAU,eAAe,CACrC,IAAI,EAAE,OAAO,EACb,OAAO,GAAE,sBAA2B,GACnC,YAAY,CA+Cd"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Source positions, for the debugger rather than for the compiler.
|
|
3
|
+
*
|
|
4
|
+
* None of this changes what the emitted code does. It decides which line a
|
|
5
|
+
* breakpoint can be set on and which column a debugger draws a marker in,
|
|
6
|
+
* which is the difference between a source map that is technically correct
|
|
7
|
+
* and one somebody can work in. The reasoning is in the comments below,
|
|
8
|
+
* because every one of these was arrived at by watching a debugger get it
|
|
9
|
+
* wrong.
|
|
10
|
+
*/
|
|
11
|
+
import * as t from '@babel/types';
|
|
12
|
+
/**
|
|
13
|
+
* Wraps an expression so a part can re-read it, and gives the wrapper its
|
|
14
|
+
* position.
|
|
15
|
+
*
|
|
16
|
+
* The position moves from the expression to the thunk rather than being copied
|
|
17
|
+
* to both. A debugger draws one marker per distinct original column on a line,
|
|
18
|
+
* and an expression that kept its own position produced two — one where it
|
|
19
|
+
* begins and one where it ends — which look identical and do the same thing.
|
|
20
|
+
* With the wrapper owning the position, every breakable place inside it
|
|
21
|
+
* reports the same column: one marker, on the expression, hit on the first
|
|
22
|
+
* evaluation and on every later one.
|
|
23
|
+
*/
|
|
24
|
+
export declare function thunk(expression: t.Expression): t.ArrowFunctionExpression;
|
|
25
|
+
/**
|
|
26
|
+
* Moves an expression's position onto the thing the compiler wrapped it in.
|
|
27
|
+
*
|
|
28
|
+
* A point rather than a range. The generator maps both ends of a node, and an
|
|
29
|
+
* end one column along is a second marker that looks identical to the first
|
|
30
|
+
* and does the same thing. A wrapper the compiler invented does not span
|
|
31
|
+
* anything in the source anyway — it belongs where the expression begins.
|
|
32
|
+
*
|
|
33
|
+
* It matters for more than tidiness: a debugger offers a breakpoint on a line
|
|
34
|
+
* only where a *statement* is mapped to it. An expression buried in a getter
|
|
35
|
+
* the compiler wrote has no statement of its own, and the line it came from
|
|
36
|
+
* cannot be stopped on at all until one carries its position.
|
|
37
|
+
*/
|
|
38
|
+
export declare function takePosition(target: t.Node, expression: t.Expression): void;
|
|
39
|
+
export declare function expressionStatement(expression: t.Expression): t.Statement;
|
|
40
|
+
/**
|
|
41
|
+
* Gives a node the compiler built the position of the code it stands for.
|
|
42
|
+
*
|
|
43
|
+
* Without this the generated statement has no position at all, so the source
|
|
44
|
+
* map has nothing to say about it — and a debugger cannot put a breakpoint on
|
|
45
|
+
* a line it cannot find. `{v}` becoming `_$insert(el, () => props.v)` is the
|
|
46
|
+
* case that matters: that call *is* the expression, and should be reachable
|
|
47
|
+
* where the expression was written.
|
|
48
|
+
*/
|
|
49
|
+
export declare function located<T extends t.Node>(node: T, source: t.Node | null | undefined): T;
|
|
50
|
+
//# sourceMappingURL=positions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"positions.d.ts","sourceRoot":"","sources":["../src/positions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAIlC;;;;;;;;;;;GAWG;AACH,wBAAgB,KAAK,CAAC,UAAU,EAAE,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,uBAAuB,CAKzE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,UAAU,GAAG,IAAI,CAM3E;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,SAAS,CAEzE;AAED;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,GAAG,IAAI,GAAG,SAAS,GAAG,CAAC,CAUvF"}
|
package/dist/props.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Destructured props, rewritten into live reads (ADR-0005).
|
|
3
|
+
*
|
|
4
|
+
* The one pass that changes what the author wrote rather than adding to it,
|
|
5
|
+
* and the reasoning for that is under `rewritePropsDestructuring`.
|
|
6
|
+
*/
|
|
7
|
+
import type { NodePath } from '@babel/traverse';
|
|
8
|
+
import * as t from '@babel/types';
|
|
9
|
+
import { type State } from './state.js';
|
|
10
|
+
/**
|
|
11
|
+
* Rewrites destructured props into live reads.
|
|
12
|
+
*
|
|
13
|
+
* `component(({ todo }) => ...)` is the shape people want to write, and it is
|
|
14
|
+
* also the shape that silently snapshots: the binding is captured once, at
|
|
15
|
+
* setup, and never changes again. The compiler makes it mean what it looks
|
|
16
|
+
* like instead — every reference to `todo` becomes `props.todo`, which is a
|
|
17
|
+
* live read that subscribes only the part performing it.
|
|
18
|
+
*
|
|
19
|
+
* The rewrite is a rename, not a wrapper: there is no runtime cost, and the
|
|
20
|
+
* emitted code is what a developer would have written by hand. What cannot be
|
|
21
|
+
* rewritten soundly is still an error rather than a guess — assigning to a
|
|
22
|
+
* destructured prop, or an array pattern, which props are not.
|
|
23
|
+
*/
|
|
24
|
+
export declare function rewritePropsDestructuring(call: NodePath<t.CallExpression>, name: string, state: State): void;
|
|
25
|
+
//# sourceMappingURL=props.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"props.d.ts","sourceRoot":"","sources":["../src/props.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAIlC,OAAO,EAAW,KAAK,KAAK,EAAE,MAAM,YAAY,CAAC;AAEjD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,cAAc,CAAC,EAChC,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,KAAK,GACX,IAAI,CAwCN"}
|
package/dist/runs.d.ts
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which function a piece of markup belongs to, and what that function owns.
|
|
3
|
+
*
|
|
4
|
+
* Two passes run before anything is compiled — `collectViews` and
|
|
5
|
+
* `collectRuns` — because both answer questions that must not depend on the
|
|
6
|
+
* order Babel happens to walk in. Everything else here is asked later, of one
|
|
7
|
+
* node at a time, and answered from what those two found.
|
|
8
|
+
*/
|
|
9
|
+
import type { NodePath } from '@babel/traverse';
|
|
10
|
+
import * as t from '@babel/types';
|
|
11
|
+
import { type Build, type RunContext, type State } from './state.js';
|
|
12
|
+
/**
|
|
13
|
+
* Finds every function this module writes markup inside, before anything is
|
|
14
|
+
* compiled.
|
|
15
|
+
*
|
|
16
|
+
* This is the line between a view of ours and a component of somebody else's,
|
|
17
|
+
* and it is drawn where it can actually be seen: **which compiler turned the
|
|
18
|
+
* markup into code.** A function that builds its result with another
|
|
19
|
+
* framework's `createElement` contains no markup for this compiler to
|
|
20
|
+
* translate, so it is not ours and is left to the adapter — even though it is
|
|
21
|
+
* a local function that returns something renderable.
|
|
22
|
+
*
|
|
23
|
+
* A pass of its own rather than a note taken while compiling, because a tag
|
|
24
|
+
* can stand above the function it names and the answer must not depend on the
|
|
25
|
+
* order Babel happens to walk in.
|
|
26
|
+
*
|
|
27
|
+
* Every enclosing function is recorded, not only the innermost: a view that
|
|
28
|
+
* builds its markup in a helper closure is still a view.
|
|
29
|
+
*/
|
|
30
|
+
export declare function collectViews(program: NodePath<t.Program>, state: State): void;
|
|
31
|
+
/**
|
|
32
|
+
* Whether a tag names a plain function declared in this module.
|
|
33
|
+
*
|
|
34
|
+
* Then the compiler knows what it is — it compiled the markup inside it — and
|
|
35
|
+
* emits the call itself. Nothing is looked up at runtime, so an installed
|
|
36
|
+
* adapter for another framework never sees it, and the decision cannot be
|
|
37
|
+
* wrong. An imported name is left to `createComponent`, which reads the mark.
|
|
38
|
+
*/
|
|
39
|
+
export declare function isLocalView(path: NodePath<t.JSXElement>, state: State): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Finds the functions that run again as a whole, and gives each one a store.
|
|
42
|
+
*
|
|
43
|
+
* A render function is the one a setup returns. The setup runs once per
|
|
44
|
+
* instance, so a `const` declared there is per instance too — which is exactly
|
|
45
|
+
* what a store has to be, and why this needs no registry and no ambient state.
|
|
46
|
+
*/
|
|
47
|
+
export declare function collectRuns(program: NodePath<t.Program>, state: State): void;
|
|
48
|
+
/** The run this markup belongs to, or `null` when it is built once. */
|
|
49
|
+
export declare function enclosingRun(path: NodePath, state: State): RunContext | null;
|
|
50
|
+
/**
|
|
51
|
+
* Whether an expression needs a value that belongs to one run of the function.
|
|
52
|
+
*
|
|
53
|
+
* This is the whole classification, and it is forced rather than chosen: an
|
|
54
|
+
* expression that names nothing from the run can be given a scope of its own
|
|
55
|
+
* and left to update itself, and one that names something from the run cannot
|
|
56
|
+
* — that value belongs to the call that produced it, so the run must write it.
|
|
57
|
+
*/
|
|
58
|
+
export declare function dependsOnRun(node: t.Node, run: RunContext | null, at: NodePath): boolean;
|
|
59
|
+
/**
|
|
60
|
+
* Whether a site can be kept between runs.
|
|
61
|
+
*
|
|
62
|
+
* Everything a run needs to write has to be something this compiler knows how
|
|
63
|
+
* to write. A spread, a `ref` or a keyed list is made once by its nature, and
|
|
64
|
+
* making one once out of a value that belongs to a single run would hold that
|
|
65
|
+
* run's value for ever — so such a site is built afresh instead, which is what
|
|
66
|
+
* happens today and is never wrong.
|
|
67
|
+
*/
|
|
68
|
+
export declare function canRetain(node: t.JSXElement, build: Build): boolean;
|
|
69
|
+
//# sourceMappingURL=runs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runs.d.ts","sourceRoot":"","sources":["../src/runs.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAMlC,OAAO,EAAW,KAAK,KAAK,EAAE,KAAK,UAAU,EAAE,KAAK,KAAK,EAAE,MAAM,YAAY,CAAC;AAE9E;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,CAiB7E;AA6BD;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAuB/E;AAED;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,CAM5E;AAwGD,uEAAuE;AACvE,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,GAAG,UAAU,GAAG,IAAI,CAa5E;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,UAAU,GAAG,IAAI,EAAE,EAAE,EAAE,QAAQ,GAAG,OAAO,CAmBxF;AA4CD;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC,UAAU,EAAE,KAAK,EAAE,KAAK,GAAG,OAAO,CAuBnE"}
|
package/dist/site.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The site a template occupies, in its two forms.
|
|
3
|
+
*
|
|
4
|
+
* Built every time it is reached, or built once and written into afterwards —
|
|
5
|
+
* which one is decided before anything is emitted, so that what comes out is
|
|
6
|
+
* all of one kind (ADR-0026).
|
|
7
|
+
*/
|
|
8
|
+
import type { NodePath } from '@babel/traverse';
|
|
9
|
+
import * as t from '@babel/types';
|
|
10
|
+
import { type State } from './state.js';
|
|
11
|
+
export declare function compileTemplate(path: NodePath<t.JSXElement>, state: State): t.Expression;
|
|
12
|
+
//# sourceMappingURL=site.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"site.d.ts","sourceRoot":"","sources":["../src/site.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAQlC,OAAO,EAAwC,KAAK,KAAK,EAAE,MAAM,YAAY,CAAC;AAI9E,wBAAgB,eAAe,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE,KAAK,EAAE,KAAK,GAAG,CAAC,CAAC,UAAU,CAWxF"}
|
package/dist/state.d.ts
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What one module's compilation knows about itself.
|
|
3
|
+
*
|
|
4
|
+
* Everything here is per-file and lives for one `transform()`. The two import
|
|
5
|
+
* helpers are the only way a pass names something from the runtime, which is
|
|
6
|
+
* what keeps the import list at the top of the output correct without anyone
|
|
7
|
+
* maintaining it: asking for a name is what adds it.
|
|
8
|
+
*/
|
|
9
|
+
import type { PluginPass } from '@babel/core';
|
|
10
|
+
import type { NodePath } from '@babel/traverse';
|
|
11
|
+
import * as t from '@babel/types';
|
|
12
|
+
export type FirsthandState = {
|
|
13
|
+
imports: Map<string, t.Identifier>;
|
|
14
|
+
templates: t.VariableDeclarator[];
|
|
15
|
+
counter: number;
|
|
16
|
+
moduleId: string;
|
|
17
|
+
/** Module-level functions markup was compiled into, in source order. */
|
|
18
|
+
views: Map<string, t.Identifier>;
|
|
19
|
+
/** Every function markup was written inside, for resolving tags locally. */
|
|
20
|
+
viewNodes: Set<t.Node>;
|
|
21
|
+
/** Whether this module is being compiled for a server render. */
|
|
22
|
+
ssr: boolean;
|
|
23
|
+
/** Whether this module's output has to be able to adopt server markup. */
|
|
24
|
+
hydratable: boolean;
|
|
25
|
+
/** Functions that run again as a whole, and where each keeps its sites. */
|
|
26
|
+
runs: Map<t.Node, RunContext>;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* What a re-running function needs in order to keep its DOM.
|
|
30
|
+
*
|
|
31
|
+
* `store` is an array declared once per instance — in the setup, which runs
|
|
32
|
+
* once — and every site inside the run takes a numbered place in it. The index
|
|
33
|
+
* is fixed at compile time, so a site inside an `if` keeps its own place
|
|
34
|
+
* whether or not the branch was taken: nothing depends on the order the run
|
|
35
|
+
* happens to reach things in, which is the rule React needs for hooks and this
|
|
36
|
+
* does not.
|
|
37
|
+
*/
|
|
38
|
+
export type RunContext = {
|
|
39
|
+
/** The function whose body re-runs. Bindings inside it belong to one run. */
|
|
40
|
+
node: t.Node;
|
|
41
|
+
store: t.Identifier;
|
|
42
|
+
next: () => number;
|
|
43
|
+
};
|
|
44
|
+
declare module '@babel/core' {
|
|
45
|
+
interface PluginPass {
|
|
46
|
+
firsthand: FirsthandState;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export type State = PluginPass;
|
|
50
|
+
export type Build = {
|
|
51
|
+
html: string[];
|
|
52
|
+
/** Navigation to the nodes a template's parts need. Runs every time. */
|
|
53
|
+
statements: t.Statement[];
|
|
54
|
+
/** Work done when the site is made: parts, listeners, refs. */
|
|
55
|
+
once: t.Statement[];
|
|
56
|
+
/** Writes the run performs into a site it already made. */
|
|
57
|
+
each: t.Statement[];
|
|
58
|
+
run: RunContext | null;
|
|
59
|
+
/** Where to resolve names from, when deciding what belongs to the run. */
|
|
60
|
+
at: NodePath;
|
|
61
|
+
next: () => t.Identifier;
|
|
62
|
+
name: (prefix: string) => t.Identifier;
|
|
63
|
+
};
|
|
64
|
+
export declare function pushOnce(build: Build, statement: t.Statement): void;
|
|
65
|
+
export declare function pushEach(build: Build, statement: t.Statement): void;
|
|
66
|
+
export declare function runtime(state: State, name: string, source?: string): t.Identifier;
|
|
67
|
+
export declare function runtimeFrom(state: State, name: string, source: string): t.Identifier;
|
|
68
|
+
/**
|
|
69
|
+
* The element an attribute or a child is being emitted onto.
|
|
70
|
+
*
|
|
71
|
+
* Four things that always travel together — where the output goes, which
|
|
72
|
+
* variable holds the node, the module's state, and the tag, which decides
|
|
73
|
+
* whether a name is a DOM property. `deferred` is the work that cannot happen
|
|
74
|
+
* until the opening tag is closed: a listener needs the node, and the node does
|
|
75
|
+
* not exist while its attributes are still being written into the HTML.
|
|
76
|
+
*/
|
|
77
|
+
export type Host = {
|
|
78
|
+
build: Build;
|
|
79
|
+
self: t.Identifier;
|
|
80
|
+
state: State;
|
|
81
|
+
deferred: (() => void)[];
|
|
82
|
+
tag: string;
|
|
83
|
+
};
|
|
84
|
+
//# sourceMappingURL=state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../src/state.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAKlC,MAAM,MAAM,cAAc,GAAG;IAC3B,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC;IACnC,SAAS,EAAE,CAAC,CAAC,kBAAkB,EAAE,CAAC;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,wEAAwE;IACxE,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC;IACjC,4EAA4E;IAC5E,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACvB,iEAAiE;IACjE,GAAG,EAAE,OAAO,CAAC;IACb,0EAA0E;IAC1E,UAAU,EAAE,OAAO,CAAC;IACpB,2EAA2E;IAC3E,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;CAC/B,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,6EAA6E;IAC7E,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;IACb,KAAK,EAAE,CAAC,CAAC,UAAU,CAAC;IACpB,IAAI,EAAE,MAAM,MAAM,CAAC;CACpB,CAAC;AAEF,OAAO,QAAQ,aAAa,CAAC;IAC3B,UAAU,UAAU;QAClB,SAAS,EAAE,cAAc,CAAC;KAC3B;CACF;AAED,MAAM,MAAM,KAAK,GAAG,UAAU,CAAC;AAE/B,MAAM,MAAM,KAAK,GAAG;IAClB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,wEAAwE;IACxE,UAAU,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC;IAC1B,+DAA+D;IAC/D,IAAI,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC;IACpB,2DAA2D;IAC3D,IAAI,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC;IACpB,GAAG,EAAE,UAAU,GAAG,IAAI,CAAC;IACvB,0EAA0E;IAC1E,EAAE,EAAE,QAAQ,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,CAAC,UAAU,CAAC;IACzB,IAAI,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,CAAC,CAAC,UAAU,CAAC;CACxC,CAAC;AAEF,wBAAgB,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,GAAG,IAAI,CAEnE;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,GAAG,IAAI,CAEnE;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,UAAU,CAEjF;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC,UAAU,CAQpF;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,IAAI,GAAG;IACjB,KAAK,EAAE,KAAK,CAAC;IACb,IAAI,EAAE,CAAC,CAAC,UAAU,CAAC;IACnB,KAAK,EAAE,KAAK,CAAC;IACb,QAAQ,EAAE,CAAC,MAAM,IAAI,CAAC,EAAE,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;CACb,CAAC"}
|