livemark 0.28.4 → 0.28.5

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.
Files changed (33) hide show
  1. package/README.md +2 -2
  2. package/build/actions/changelog/build.d.ts +1 -1
  3. package/build/actions/changelog/build.js +5 -5
  4. package/build/actions/changelog/build.unit.js +6 -6
  5. package/build/actions/target/build.d.ts +9 -5
  6. package/build/actions/target/build.js +14 -9
  7. package/build/actions/target/build.unit.js +17 -2
  8. package/build/actions/target/clear.d.ts +2 -2
  9. package/build/actions/target/clear.js +11 -9
  10. package/build/actions/target/clear.unit.js +10 -3
  11. package/build/commands/clear.d.ts +1 -1
  12. package/build/commands/clear.js +6 -5
  13. package/build/helpers/tailwind-sources.unit.js +4 -4
  14. package/build/helpers/target-dir.d.ts +2 -0
  15. package/build/helpers/target-dir.js +11 -0
  16. package/build/helpers/target-export.unit.js +2 -2
  17. package/build/plugins/vite-livemark.d.ts +2 -1
  18. package/build/plugins/vite-livemark.js +20 -9
  19. package/package.json +1 -1
  20. package/skills/livemark-configuration/SKILL.md +1 -1
  21. package/skills/livemark-customization/SKILL.md +1 -1
  22. package/skills/livemark-deployment/SKILL.md +1 -1
  23. package/source/actions/changelog/build.ts +4 -5
  24. package/source/actions/changelog/build.unit.ts +5 -5
  25. package/source/actions/target/build.ts +29 -9
  26. package/source/actions/target/build.unit.ts +24 -1
  27. package/source/actions/target/clear.ts +9 -8
  28. package/source/actions/target/clear.unit.ts +9 -2
  29. package/source/commands/clear.ts +5 -4
  30. package/source/helpers/tailwind-sources.unit.ts +3 -3
  31. package/source/helpers/target-dir.ts +12 -0
  32. package/source/helpers/target-export.unit.ts +1 -1
  33. package/source/plugins/vite-livemark.ts +19 -9
@@ -1,14 +1,15 @@
1
- import { rmSync } from "node:fs"
2
- import { join } from "node:path"
1
+ import { cacheDirFor, removeTargetDir } from "../../helpers/target-dir.ts"
3
2
  import { targetDirFor } from "./build.ts"
4
3
 
5
4
  /**
6
- * Wipe the project's target dir so the next run rebuilds it from scratch.
5
+ * Wipe the project's target dirs and cache so the next run rebuilds them from scratch.
7
6
  */
8
7
  export function clearTarget(configPath: string) {
9
- const targetDir = targetDirFor(configPath)
10
- // Unlink the dependency link first so the recursive remove cannot reach the store.
11
- rmSync(join(targetDir, "node_modules"), { force: true })
12
- rmSync(targetDir, { recursive: true, force: true })
13
- return targetDir
8
+ const targetDirs = [
9
+ targetDirFor(configPath, "serve"),
10
+ targetDirFor(configPath, "build"),
11
+ cacheDirFor(configPath),
12
+ ]
13
+ for (const targetDir of targetDirs) removeTargetDir(targetDir)
14
+ return targetDirs
14
15
  }
@@ -3,22 +3,29 @@ import { mkdir, symlink, writeFile } from "node:fs/promises"
3
3
  import { join } from "node:path"
4
4
  import { temporaryDirectoryTask } from "tempy"
5
5
  import { describe, expect, it } from "vite-plus/test"
6
+ import { cacheDirFor } from "../../helpers/target-dir.ts"
6
7
  import { targetDirFor } from "./build.ts"
7
8
  import { clearTarget } from "./clear.ts"
8
9
 
9
10
  describe("clearTarget", () => {
10
- it("removes the target dir without following its dependency link", () =>
11
+ it("removes the target dirs without following their dependency link", () =>
11
12
  temporaryDirectoryTask(async root => {
12
13
  const configPath = join(root, "livemark.config.ts")
13
14
  const targetDir = targetDirFor(configPath)
15
+ const buildDir = targetDirFor(configPath, "build")
16
+ const cacheDir = cacheDirFor(configPath)
17
+ await mkdir(buildDir, { recursive: true })
18
+ await mkdir(cacheDir, { recursive: true })
14
19
  await mkdir(join(targetDir, "cache"), { recursive: true })
15
20
  await writeFile(join(targetDir, "cache", "entry.md"), "cached")
16
21
  await mkdir(join(root, "deps"))
17
22
  await writeFile(join(root, "deps", "kept.js"), "")
18
23
  await symlink(join(root, "deps"), join(targetDir, "node_modules"), "junction")
19
24
 
20
- expect(clearTarget(configPath)).toBe(targetDir)
25
+ expect(clearTarget(configPath)).toEqual([targetDir, buildDir, cacheDir])
21
26
  expect(existsSync(targetDir)).toBe(false)
27
+ expect(existsSync(buildDir)).toBe(false)
28
+ expect(existsSync(cacheDir)).toBe(false)
22
29
  expect(existsSync(join(root, "deps", "kept.js"))).toBe(true)
23
30
  expect(() => clearTarget(configPath)).not.toThrow()
24
31
  }))
@@ -4,12 +4,13 @@ import { loadConfig } from "../actions/config/load.ts"
4
4
  import { clearTarget } from "../actions/target/clear.ts"
5
5
 
6
6
  /**
7
- * Wipe the generated `.livemark/.target/` mount.
7
+ * Wipe the generated `.livemark/.serve/` and `.livemark/.build/` mounts and `.livemark/.cache/`.
8
8
  */
9
9
  export const clear = new Command("clear")
10
- .description("Wipe the generated .livemark/.target/ mount")
10
+ .description("Wipe the generated .livemark/.serve/, .build/ and .cache/")
11
11
  .action(async () => {
12
12
  const config = await loadConfig()
13
- const targetDir = clearTarget(config.configPath)
14
- console.log(`Cleared ${pc.dim(targetDir)}`)
13
+ for (const targetDir of clearTarget(config.configPath)) {
14
+ console.log(`Cleared ${pc.dim(targetDir)}`)
15
+ }
15
16
  })
@@ -1,14 +1,14 @@
1
1
  import { describe, expect, it } from "vite-plus/test"
2
2
  import { excludeTailwindSources } from "./tailwind-sources.ts"
3
3
 
4
- const targetDir = "/project/.livemark/.target"
4
+ const targetDir = "/project/.livemark/.serve"
5
5
 
6
6
  describe("excludeTailwindSources", () => {
7
7
  it("excludes the dependency link and the content cache from a Tailwind entry", () => {
8
8
  const css = `@import "tailwindcss";\n@import "./shape.css";`
9
9
  expect(excludeTailwindSources({ css, targetDir })).toBe(
10
- `${css}\n@source not "/project/.livemark/.target/node_modules";\n` +
11
- `@source not "/project/.livemark/.target/.content-collections/cache";\n`,
10
+ `${css}\n@source not "/project/.livemark/.serve/node_modules";\n` +
11
+ `@source not "/project/.livemark/.serve/.content-collections/cache";\n`,
12
12
  )
13
13
  })
14
14
 
@@ -0,0 +1,12 @@
1
+ import { rmSync } from "node:fs"
2
+ import { dirname, join } from "node:path"
3
+
4
+ export function removeTargetDir(targetDir: string) {
5
+ // Unlink the dependency link first so the recursive remove cannot reach the store.
6
+ rmSync(join(targetDir, "node_modules"), { force: true })
7
+ rmSync(targetDir, { recursive: true, force: true })
8
+ }
9
+
10
+ export function cacheDirFor(configPath: string) {
11
+ return join(dirname(configPath), ".livemark", ".cache")
12
+ }
@@ -3,7 +3,7 @@ import { describe, expect, it } from "vite-plus/test"
3
3
  import packageJson from "../../package.json" with { type: "json" }
4
4
  import { resolveTargetExport } from "./target-export.ts"
5
5
 
6
- const targetDir = "/project/.livemark/.target"
6
+ const targetDir = "/project/.livemark/.serve"
7
7
 
8
8
  function resolveId(id: string) {
9
9
  return resolveTargetExport({ id, targetDir, exports: packageJson.exports })
@@ -42,7 +42,8 @@ const LOCKFILES = [
42
42
  const VIRTUAL_ID = "livemark:virtual"
43
43
  const VIRTUAL_RESOLVED_ID = `\0${VIRTUAL_ID}`
44
44
 
45
- /** Owns the project's `.livemark/.target/` mount: synthesizes it via
45
+ /** Owns the project's `.livemark/.serve/` mount (`.build/` when building, so a build
46
+ * never rewrites a running dev server's files): synthesizes it via
46
47
  * `buildTarget()`, returns the Vite config that anchors there, and
47
48
  * copies `.livemark/` edits (plus livemark's `source/` in its own dev)
48
49
  * into the target. Vite watches the target natively, so its own HMR
@@ -58,6 +59,7 @@ export function livemark(opts: LivemarkOptions): Plugin {
58
59
  targetDir = buildTarget({
59
60
  configPath: opts.config.configPath,
60
61
  sourceDir: SOURCE_DIR,
62
+ command: env.command === "build" || env.isPreview ? "build" : "serve",
61
63
  })
62
64
  const base: ViteUserConfig = {
63
65
  root: targetDir,
@@ -137,14 +139,22 @@ export function livemark(opts: LivemarkOptions): Plugin {
137
139
  return
138
140
  }
139
141
  if (isWithin(file, targetDir) || isWithin(file, outDir)) return
140
- const overlayHit = matchPath(file, overridesRoot)
141
- if (overlayHit) {
142
- syncOverlay(overlayHit, kind, targetDir, overridesRoot)
143
- return
144
- }
145
- const sourceHit = matchPath(file, SOURCE_DIR)
146
- if (sourceHit && !sourceHit.rel.includes("routeTree.gen.ts")) {
147
- syncSource(sourceHit, kind, targetDir, overridesRoot)
142
+ // A watcher callback that throws kills the server, and a copy racing another
143
+ // writer of the target (an editor's atomic save, `livemark clear`) fails.
144
+ try {
145
+ const overlayHit = matchPath(file, overridesRoot)
146
+ if (overlayHit) {
147
+ syncOverlay(overlayHit, kind, targetDir, overridesRoot)
148
+ return
149
+ }
150
+ const sourceHit = matchPath(file, SOURCE_DIR)
151
+ if (sourceHit && !sourceHit.rel.includes("routeTree.gen.ts")) {
152
+ syncSource(sourceHit, kind, targetDir, overridesRoot)
153
+ }
154
+ } catch (error) {
155
+ server.config.logger.error(`[livemark] failed to sync ${file}: ${error}`, {
156
+ error: error instanceof Error ? error : undefined,
157
+ })
148
158
  }
149
159
  }
150
160
  },