@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
package/dist/strict.d.ts
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The four things strict reactivity refuses to compile (ADR-0019).
|
|
3
|
+
*
|
|
4
|
+
* Every rule here stops a build, so every rule here is deliberately narrow:
|
|
5
|
+
* a false positive costs somebody a working program, and a false negative
|
|
6
|
+
* costs them the warning they would have got anyway the first time they looked
|
|
7
|
+
* at the screen. Where a shape could go either way, it is allowed.
|
|
8
|
+
*
|
|
9
|
+
* All four are *refusals*. Nothing in this module rewrites anything.
|
|
10
|
+
*/
|
|
11
|
+
import type { NodePath } from '@babel/traverse';
|
|
12
|
+
import * as t from '@babel/types';
|
|
13
|
+
/**
|
|
14
|
+
* Rejects a value that is read once in a setup and then kept (ADR-0019).
|
|
15
|
+
*
|
|
16
|
+
* The setup runs one time per instance, so `const total = props.total` is a
|
|
17
|
+
* number from the moment it is read and will not move again. Nothing throws at
|
|
18
|
+
* runtime — the number is simply old — which is why this exists.
|
|
19
|
+
*
|
|
20
|
+
* Deliberately narrow, because a false positive here stops a build. Only a
|
|
21
|
+
* declaration whose initialiser is *nothing but* a read is reported:
|
|
22
|
+
* identifiers, member accesses, literals and the operators between them. A
|
|
23
|
+
* call is never reported, which leaves `signal(props.initial)`, `peek()`,
|
|
24
|
+
* `computed(...)` and every handler alone — including `snapshot(...)`, the way
|
|
25
|
+
* to say that reading once is the point.
|
|
26
|
+
*/
|
|
27
|
+
export declare function checkKeptReads(setup: NodePath<t.Function>, name: string): void;
|
|
28
|
+
/**
|
|
29
|
+
* Rejects a view chosen once, in the setup, from something that changes.
|
|
30
|
+
*
|
|
31
|
+
* ```tsx
|
|
32
|
+
* // Decided while the component was built, and never again:
|
|
33
|
+
* return open.value ? <Form /> : <Button />;
|
|
34
|
+
*
|
|
35
|
+
* // A part, re-evaluated when `open` changes:
|
|
36
|
+
* return <>{open.value ? <Form /> : <Button />}</>;
|
|
37
|
+
* ```
|
|
38
|
+
*
|
|
39
|
+
* The two look the same and behave completely differently, because a setup
|
|
40
|
+
* runs once per instance: the first form freezes whichever branch was true at
|
|
41
|
+
* setup, and nothing throws — the screen is simply wrong, later, in a way that
|
|
42
|
+
* reads as a broken button.
|
|
43
|
+
*
|
|
44
|
+
* Only the **returned expression** is examined, and only when a signal decides
|
|
45
|
+
* which view it produces. A read *inside* JSX is a part and is left alone; so
|
|
46
|
+
* is a return with no JSX in it at all, which is somebody's helper rather than
|
|
47
|
+
* a view.
|
|
48
|
+
*
|
|
49
|
+
* Deliberately narrow, because a false positive here stops a build. A `.value`
|
|
50
|
+
* read is reported and a **prop read is not**: a signal exists in order to
|
|
51
|
+
* change, while a prop may be fixed for the life of an instance — a recursive
|
|
52
|
+
* `<Nested depth={props.depth - 1} />` chooses its shape once on purpose, and
|
|
53
|
+
* a rule that could not tell the difference would refuse it.
|
|
54
|
+
*/
|
|
55
|
+
export declare function checkDecidedOnce(setup: NodePath<t.Function>, name: string): void;
|
|
56
|
+
/**
|
|
57
|
+
* Rejects the two things a render function cannot do.
|
|
58
|
+
*
|
|
59
|
+
* **Nothing persistent is made in a run.** A signal, a computed, an effect or
|
|
60
|
+
* a resource is a thing that outlives the moment it was made; a run happens
|
|
61
|
+
* again, so one made there would be made again, and the one before it thrown
|
|
62
|
+
* away. That is not a rule about order — it is the same rule as everywhere
|
|
63
|
+
* else in Firsthand, said once: persistent things are made in the setup.
|
|
64
|
+
*
|
|
65
|
+
* **Repeated markup carries a key.** A site is identified by where it stands,
|
|
66
|
+
* which answers for markup that appears once. Markup inside a loop appears
|
|
67
|
+
* many times from one place, and only a key can say which of them is which.
|
|
68
|
+
* Without one, a run would take the rows apart and build them again — silently,
|
|
69
|
+
* losing whatever they held.
|
|
70
|
+
*/
|
|
71
|
+
export declare function checkRunBody(setup: NodePath<t.Function>, name: string): void;
|
|
72
|
+
//# sourceMappingURL=strict.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"strict.d.ts","sourceRoot":"","sources":["../src/strict.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAEhD,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAMlC;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CA8B9E;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CA+BhF;AAmCD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAoB5E"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A host element: the markup that goes into the `<template>`, and the parts
|
|
3
|
+
* that write into a clone of it (ADR-0009).
|
|
4
|
+
*
|
|
5
|
+
* Where that clone lives between runs — built every time, or built once and
|
|
6
|
+
* written into — is `site.ts`.
|
|
7
|
+
*/
|
|
8
|
+
import * as t from '@babel/types';
|
|
9
|
+
import { type Build, type State } from './state.js';
|
|
10
|
+
export declare function emitElement(node: t.JSXElement, build: Build, self: t.Identifier, state: State): void;
|
|
11
|
+
//# sourceMappingURL=template.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template.d.ts","sourceRoot":"","sources":["../src/template.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,CAAC,MAAM,cAAc,CAAC;AAmBlC,OAAO,EAIL,KAAK,KAAK,EAGV,KAAK,KAAK,EACX,MAAM,YAAY,CAAC;AAEpB,wBAAgB,WAAW,CACzB,IAAI,EAAE,CAAC,CAAC,UAAU,EAClB,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,CAAC,CAAC,UAAU,EAClB,KAAK,EAAE,KAAK,GACX,IAAI,CA2BN"}
|
package/dist/transform.d.ts
CHANGED
|
@@ -10,92 +10,20 @@
|
|
|
10
10
|
*
|
|
11
11
|
* The transform emits calls against the published protocol in
|
|
12
12
|
* `@firsthandjs/dom/internal` and has no privileged access to the runtime.
|
|
13
|
-
*/
|
|
14
|
-
import type { PluginObject } from '@babel/core';
|
|
15
|
-
import * as t from '@babel/types';
|
|
16
|
-
type FirsthandState = {
|
|
17
|
-
imports: Map<string, t.Identifier>;
|
|
18
|
-
templates: t.VariableDeclarator[];
|
|
19
|
-
counter: number;
|
|
20
|
-
moduleId: string;
|
|
21
|
-
/** Module-level functions markup was compiled into, in source order. */
|
|
22
|
-
views: Map<string, t.Identifier>;
|
|
23
|
-
/** Every function markup was written inside, for resolving tags locally. */
|
|
24
|
-
viewNodes: Set<t.Node>;
|
|
25
|
-
/** Whether this module is being compiled for a server render. */
|
|
26
|
-
ssr: boolean;
|
|
27
|
-
/** Whether this module's output has to be able to adopt server markup. */
|
|
28
|
-
hydratable: boolean;
|
|
29
|
-
/** Functions that run again as a whole, and where each keeps its sites. */
|
|
30
|
-
runs: Map<t.Node, RunContext>;
|
|
31
|
-
};
|
|
32
|
-
/**
|
|
33
|
-
* What a re-running function needs in order to keep its DOM.
|
|
34
13
|
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
14
|
+
* | Module | What it decides |
|
|
15
|
+
* | --------------- | --------------------------------------------------- |
|
|
16
|
+
* | `plugin.ts` | which pass runs when |
|
|
17
|
+
* | `components.ts` | what a `component(...)` call gains |
|
|
18
|
+
* | `strict.ts` | what will not compile at all (ADR-0019) |
|
|
19
|
+
* | `props.ts` | destructured props as live reads (ADR-0005) |
|
|
20
|
+
* | `runs.ts` | which function a piece of markup belongs to |
|
|
21
|
+
* | `lists.ts` | `.map` with a key as a keyed list part |
|
|
22
|
+
* | `jsx.ts` | component call, server markup, or template |
|
|
23
|
+
* | `template.ts` | the browser's `<template>` and the parts into it |
|
|
24
|
+
* | `markup.ts` | the server's string and the holes in it |
|
|
25
|
+
* | `attributes.ts` | one attribute, inlined or written |
|
|
41
26
|
*/
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
node: t.Node;
|
|
45
|
-
store: t.Identifier;
|
|
46
|
-
next: () => number;
|
|
47
|
-
};
|
|
48
|
-
declare module '@babel/core' {
|
|
49
|
-
interface PluginPass {
|
|
50
|
-
firsthand: FirsthandState;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
export type FirsthandPluginOptions = {
|
|
54
|
-
/** Package name used when hashing stable component ids (ADR-0004). */
|
|
55
|
-
packageName?: string;
|
|
56
|
-
/**
|
|
57
|
-
* Refuse to compile a value that is read once in a setup and then kept.
|
|
58
|
-
*
|
|
59
|
-
* **On by default.** The rule only sees declarations whose initialiser is
|
|
60
|
-
* nothing but a read, which is the shape that is almost always a mistake;
|
|
61
|
-
* anything containing a call is left alone. `false` turns it off for a
|
|
62
|
-
* codebase that has such a read on purpose and would rather not mark it with
|
|
63
|
-
* `snapshot()` — see `checkKeptReads` (ADR-0019).
|
|
64
|
-
*/
|
|
65
|
-
strictReactivity?: boolean;
|
|
66
|
-
/**
|
|
67
|
-
* Name the cells a module creates, for devtools.
|
|
68
|
-
*
|
|
69
|
-
* A runtime cannot see that `const count = signal(0)` is called `count`, and
|
|
70
|
-
* `new Error().stack` reports a position in the *compiled* module — the
|
|
71
|
-
* browser does not apply source maps to `error.stack`, so the line it names
|
|
72
|
-
* is not the line that was written. The compiler knows both, so it says so.
|
|
73
|
-
*
|
|
74
|
-
* Off by default and turned on by the Vite plugin while serving: a
|
|
75
|
-
* production build emits nothing.
|
|
76
|
-
*/
|
|
77
|
-
devtools?: boolean;
|
|
78
|
-
/**
|
|
79
|
-
* Compile for a server render.
|
|
80
|
-
*
|
|
81
|
-
* The same source, emitted against `@firsthandjs/server/internal` instead of
|
|
82
|
-
* `@firsthandjs/dom/internal`: markup is built as a string rather than as
|
|
83
|
-
* nodes, and the things a server cannot do — listeners, refs, retained
|
|
84
|
-
* sites — are not emitted at all.
|
|
85
|
-
*
|
|
86
|
-
* The Vite plugin sets this from the bundler's own `ssr` flag, so an
|
|
87
|
-
* application configures nothing.
|
|
88
|
-
*/
|
|
89
|
-
ssr?: boolean;
|
|
90
|
-
/**
|
|
91
|
-
* Emit navigation that can walk server markup.
|
|
92
|
-
*
|
|
93
|
-
* An application that hydrates needs it; one that does not should leave it
|
|
94
|
-
* off, because it turns two property reads per dynamic position into two
|
|
95
|
-
* calls. The Vite plugin sets it for a project that has a server build.
|
|
96
|
-
*/
|
|
97
|
-
hydratable?: boolean;
|
|
98
|
-
};
|
|
99
|
-
export default function firsthandPlugin(_api: unknown, options?: FirsthandPluginOptions): PluginObject;
|
|
100
|
-
export {};
|
|
27
|
+
export { default } from './plugin.js';
|
|
28
|
+
export type { FirsthandPluginOptions } from './options.js';
|
|
101
29
|
//# sourceMappingURL=transform.d.ts.map
|
package/dist/transform.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../src/transform.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../src/transform.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAEtC,YAAY,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/vite.js
CHANGED
package/package.json
CHANGED