@samva/vite 0.5.0 → 0.7.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/AGENTS.md +77 -78
- package/README.md +0 -2
- package/dist/editor/assets/index-BeVA-Ur2.js +32 -0
- package/dist/editor/assets/index-Dz2CE64u.css +2 -0
- package/dist/editor/index.html +2 -2
- package/dist/index.d.ts +8 -2
- package/dist/index.js +42 -15
- package/package.json +5 -5
- package/dist/editor/assets/index-BZ-5-1V0.js +0 -31
- package/dist/editor/assets/index-Cg4x6ewh.css +0 -2
package/AGENTS.md
CHANGED
|
@@ -1,88 +1,87 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @samva/vite agent guide
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
`@samva/vite` is the local authoring toolchain for Samva templates written with `@samva/markup`: a
|
|
4
|
+
Vite plugin that serves the visual editor, and programmatic entry points that build, render, and
|
|
5
|
+
export a template project. It compiles nothing itself; every render goes through
|
|
6
|
+
`@samva/markup/compiler`'s `compileEmailProject`, the same compile step a hosted Samva build runs, so
|
|
7
|
+
a local render does not drift from a published one. Publishing and hosted synchronization are not
|
|
8
|
+
here: they are ordinary Git plus `samva templates publish` from `@samva/cli` (see
|
|
9
|
+
`samva templates --help`).
|
|
6
10
|
|
|
7
|
-
|
|
8
|
-
project lockfile so local preview, check, and build use the same compiler version as the project.
|
|
11
|
+
## Entry points
|
|
9
12
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
- `@samva/vite` — `samvaEditor()`, the plugin you add to `vite.config.ts`. Options are typed by
|
|
14
|
+
`SamvaEditorPluginOptions`; the README lists them.
|
|
15
|
+
- `@samva/vite/build` — `buildTemplates()` and `createTemplateBuildSession()` for programmatic
|
|
16
|
+
checks and builds. The `samva` CLI loads this module from your project, not from its own bundle.
|
|
17
|
+
- `@samva/vite/project` — the folder-of-templates surface: `loadEmailCatalog()`,
|
|
18
|
+
`renderEmailFixtures()`, `createEmailProjectSession()`, `exportEmailProject()`.
|
|
19
|
+
- `@samva/vite/email` — `createEmailRenderer()` and `renderEmailProject()` for rendering one email
|
|
20
|
+
project from source.
|
|
21
|
+
- `@samva/vite/emit` — module-preview integration for structured SMS and WhatsApp entries.
|
|
14
22
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
23
|
+
Install `@samva/markup`, `@samva/vite`, and the `vite` peer as dev dependencies of the template
|
|
24
|
+
project and keep them in its lockfile. The CLI's `templates check`, `templates build`, and the
|
|
25
|
+
editor all resolve these packages from the project, so the lockfile is what pins the compiler
|
|
26
|
+
version your previews, checks, and builds use.
|
|
19
27
|
|
|
20
|
-
|
|
21
|
-
revision check and a fresh comparison against disk; SMS and WhatsApp stay read-only. A change
|
|
22
|
-
published without a client is what the editor reads as a foreign edit, so nothing the editor itself
|
|
23
|
-
did may reach it that way. A save and a fixture switch both run in the store's mutation queue, so no
|
|
24
|
-
rebuild can straddle one and publish the difference anonymously; the editor's write comes back
|
|
25
|
-
through the file watcher like any other edit, and a changed file that still holds the bytes its
|
|
26
|
-
entry was built from re-evaluates nothing. Watcher events arrive in bursts and one rebuild re-reads
|
|
27
|
-
the whole project, so a rebuild that has not started yet covers every event queued before it. Every discovered entry is imported once through the dev
|
|
28
|
-
server's own SSR graph, and a default export that is a template definition takes the email lane —
|
|
29
|
-
compiled and rendered through `compileEmailProject`, so a local render cannot drift from a published
|
|
30
|
-
one. Email requires an executable definition. Structured SMS/WhatsApp entries emit SML, and
|
|
31
|
-
for SMS and WhatsApp an invalid current TSX keeps and visibly labels the last successful emission
|
|
32
|
-
while the same file remains discovered; deleting the file removes it.
|
|
28
|
+
## How you hurt yourself here
|
|
33
29
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
30
|
+
- **Expecting your Vite config to apply to email rendering.** Every email render, in the editor,
|
|
31
|
+
the CLI, and the programmatic entry points, runs in an evaluator this package roots at its own
|
|
32
|
+
directory with no config file, so your `vite.config.ts` aliases and plugins never reach an email
|
|
33
|
+
template. Bare imports resolve from the package root, which is what makes `@samva/markup` resolve
|
|
34
|
+
under both hoisted and per-package installs. Import shared helpers by relative path; an alias that
|
|
35
|
+
works elsewhere in your app fails here.
|
|
36
|
+
- **Side effects at module scope.** Discovery imports every `.tsx` under the templates directory
|
|
37
|
+
and asks whether its default export is a template definition, and a rebuild re-reads the whole
|
|
38
|
+
project. Top-level code in every module, helpers included, runs whenever the project is
|
|
39
|
+
evaluated; keep it free of I/O and mutable global state.
|
|
40
|
+
- **Relying on a file path as template identity.** Identity is the `id` the definition declares.
|
|
41
|
+
Two definitions declaring one id is a reported error, and moving a file does not change its id.
|
|
42
|
+
Helper modules need no marker or exclusion list: a module is a template only if its default export
|
|
43
|
+
is a definition.
|
|
44
|
+
- **Exporting for delivery with the default asset base.** `exportEmailProject` renders with relative
|
|
45
|
+
URLs and writes each page at `templates/<id>/<fixture>.html` beside a content-addressed `assets/`
|
|
46
|
+
directory, so its default base, `DEFAULT_EXPORT_ASSET_BASE`, only works when those files are
|
|
47
|
+
browsed from disk. An inbox has no directory to resolve a relative URL against, so delivery refuses
|
|
48
|
+
one. For an export you will send, pass the https origin that will serve the assets.
|
|
49
|
+
- **Reusing a renderer without a stable namespace.** `createEmailRenderer` keeps one evaluator
|
|
50
|
+
across renders, as a dev server does, and gives each project its own module-id namespace. Omit
|
|
51
|
+
`namespace` and every `load` takes a fresh one, which isolates unrelated projects but grows the
|
|
52
|
+
graph on every reload. A watch loop over one project passes the same `namespace` each time so its
|
|
53
|
+
ids stay stable. Each `load` re-evaluates its own namespace's modules; `invalidate()` also drops
|
|
54
|
+
the modules namespaces share. `close()` releases the evaluator.
|
|
55
|
+
- **Expecting the email editor to overwrite concurrent edits.** The editor writes back to the
|
|
56
|
+
entry's canonical `.tsx` source after checking that the file on disk is still the revision it
|
|
57
|
+
read, so a change you saved elsewhere is not overwritten; reload the entry and retry. SMS and
|
|
58
|
+
WhatsApp entries are read-only in the editor.
|
|
42
59
|
|
|
43
|
-
|
|
44
|
-
is `@samva/markup/compiler`'s `compileEmailProject`, the same call the hosted build makes, and this
|
|
45
|
-
package owns only module resolution and evaluation. The asset base is an explicit input, so a
|
|
46
|
-
build and an export can address the same content from different origins. Both entry points evaluate
|
|
47
|
-
the compiler's generated wrapper rather than the authored entry: the render has to happen inside the
|
|
48
|
-
graph the project's stylesheets registered into.
|
|
60
|
+
## Rules
|
|
49
61
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
62
|
+
- **Template entries are `.tsx`.** Discovery ignores every other extension.
|
|
63
|
+
- **Template ids and fixture keys match `TEMPLATE_NAME_PATTERN`** from `@samva/markup/template`,
|
|
64
|
+
because both are written into export paths. Code that builds a path from them imports that
|
|
65
|
+
pattern instead of restating it.
|
|
66
|
+
- **Fixtures are validated against the template's own schema before they render.** A bad fixture is
|
|
67
|
+
a finding on that template, not a runtime surprise at send time.
|
|
68
|
+
- **One failure stays with its template.** A refused render reports against its fixture, and an
|
|
69
|
+
email entry that does not build stays in the catalog with a null render and the findings that
|
|
70
|
+
stopped it. SMS and WhatsApp entries that stop compiling keep their last successful preview,
|
|
71
|
+
labeled stale, until the file compiles again or is deleted.
|
|
72
|
+
- **Results are values.** `@samva/vite/build` and the preview surfaces return discriminated results
|
|
73
|
+
with an `ok` field, and `@samva/vite/emit` passes through the compiler's better-result `Result`. A
|
|
74
|
+
missing `vite` peer, or an entry whose default export is not a template definition where one is
|
|
75
|
+
required, throws.
|
|
76
|
+
- **The asset base is a build input, not authored source.** The same content can be built for one
|
|
77
|
+
origin and exported for another. The dev server is not an https origin, so editor previews
|
|
78
|
+
reference assets through the editor's own route by path.
|
|
56
79
|
|
|
57
|
-
|
|
58
|
-
shared components and CSS between them; which `.tsx` files are templates is decided by evaluating
|
|
59
|
-
the compiler's generated wrapper and asking whether the default export is a template definition, so
|
|
60
|
-
an ordinary helper module needs no marker and no exclusion list. Identity is the id the definition
|
|
61
|
-
declares, never its path, and two definitions declaring one id is a reported error. Fixtures are
|
|
62
|
-
validated against the template's own schema before they render, so a bad fixture is a source defect
|
|
63
|
-
the author sees locally.
|
|
80
|
+
## Proving your setup
|
|
64
81
|
|
|
65
|
-
`
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
mapping.
|
|
72
|
-
|
|
73
|
-
A refused render reports against the one fixture rather than throwing at the caller: one template
|
|
74
|
-
that cannot render must not take the rest of the catalog with it.
|
|
75
|
-
|
|
76
|
-
The evaluator roots itself at this package's own directory and refuses an ambient Vite config.
|
|
77
|
-
Virtual ids have no directory, so bare imports resolve against the server root; rooting here is what
|
|
78
|
-
makes `@samva/markup` resolve under a per-package install as well as a hoisted one.
|
|
79
|
-
|
|
80
|
-
A golden-digest test in `tests/email-parity.test.ts` pins this adapter's output against the same
|
|
81
|
-
value the hosted build asserts in `apps/agents/tests/workerd/email-parity.test.ts`.
|
|
82
|
-
|
|
83
|
-
## Verification
|
|
84
|
-
|
|
85
|
-
`bun run --filter @samva/vite test:browser` builds the plugin and embedded editor, then runs the
|
|
86
|
-
Chromium source-editing integration tests. `test:browser:cross` runs Chromium, Firefox, and WebKit.
|
|
87
|
-
These tests own temporary template projects and plugin servers; the editor library's browser suite
|
|
88
|
-
tests its standalone host separately.
|
|
82
|
+
- `samva templates check --dir <templates-dir>` executes every declared fixture and reports
|
|
83
|
+
findings; `--watch` keeps it running while you edit.
|
|
84
|
+
- `vite` with `samvaEditor()` configured serves the editor at the configured `route`; every entry
|
|
85
|
+
should appear with its fixtures.
|
|
86
|
+
- `exportEmailProject({ dir, out })` writes browsable HTML and text for every fixture and a
|
|
87
|
+
`catalog.json` with the asset mapping and findings, without Samva credentials.
|
package/README.md
CHANGED
|
@@ -152,5 +152,3 @@ Export writes `templates/<id>/<fixture>.html` and `.txt`, content-addressed file
|
|
|
152
152
|
and `catalog.json` with the asset mapping and findings. The default `../../assets` base resolves
|
|
153
153
|
from each exported page. For delivery, supply the actual HTTPS `assetBase` and serve those bytes
|
|
154
154
|
there; relative URLs are for local export. External HTTPS images stay external references.
|
|
155
|
-
|
|
156
|
-
The runnable `examples/email-starter` workspace exercises the authoring setup.
|