@invisibleloop/pulse 0.20.57 → 0.20.58
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/package.json +2 -2
- package/public/.pulse-ui-version +1 -1
- package/src/cli/dev.js +10 -0
- package/src/cli/discover.js +2 -1
- package/src/cli/reload-hooks.js +35 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@invisibleloop/pulse",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.58",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "AI-first frontend framework. The spec is the source of truth.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -76,7 +76,7 @@
|
|
|
76
76
|
"scripts": {
|
|
77
77
|
"dev": "node --watch src/cli/dev.js",
|
|
78
78
|
"build": "node scripts/build.js",
|
|
79
|
-
"test": "node src/spec/schema.test.js && node src/runtime/runtime.test.js && node src/runtime/navigate.test.js && node src/runtime/morph.test.js && node src/runtime/ssr.test.js && node src/runtime/image.test.js && node src/server/server.test.js && node src/cli/cli.test.js && node src/cli/validate.test.js && node src/cli/diagnose.test.js && node src/cli/check-bundles.test.js && node src/cli/review.test.js && node src/cli/process-utils.test.js && node src/cli/stamp.test.js && node src/cli/feedback.test.js && node src/cli/update.test.js && node src/cli/dev-host.test.js && node src/ui/ui.test.js && node src/testing/testing.test.js && node src/store/store.test.js && node src/md/md.test.js && node scripts/strip-server.test.js && node scripts/css-purge.test.js && node scripts/release-version.test.js && node src/mcp/mcp.test.js && node src/mcp/guards.test.js",
|
|
79
|
+
"test": "node src/spec/schema.test.js && node src/runtime/runtime.test.js && node src/runtime/navigate.test.js && node src/runtime/morph.test.js && node src/runtime/ssr.test.js && node src/runtime/image.test.js && node src/server/server.test.js && node src/cli/cli.test.js && node src/cli/validate.test.js && node src/cli/diagnose.test.js && node src/cli/check-bundles.test.js && node src/cli/review.test.js && node src/cli/process-utils.test.js && node src/cli/stamp.test.js && node src/cli/feedback.test.js && node src/cli/update.test.js && node src/cli/dev-host.test.js && node src/cli/dev-reload.test.js && node src/ui/ui.test.js && node src/testing/testing.test.js && node src/store/store.test.js && node src/md/md.test.js && node scripts/strip-server.test.js && node scripts/css-purge.test.js && node scripts/release-version.test.js && node src/mcp/mcp.test.js && node src/mcp/guards.test.js",
|
|
80
80
|
"typecheck": "tsc --noEmit",
|
|
81
81
|
"docs": "node --watch src/cli/dev.js --root ../../docs --port 4000",
|
|
82
82
|
"docs:start": "node ../../docs/server.js"
|
package/public/.pulse-ui-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
0.20.
|
|
1
|
+
0.20.58
|
package/src/cli/dev.js
CHANGED
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
|
|
11
11
|
import path from 'path'
|
|
12
12
|
import fs from 'fs'
|
|
13
|
+
import { register } from 'node:module'
|
|
14
|
+
import { pathToFileURL } from 'node:url'
|
|
13
15
|
import { createServer } from '../server/index.js'
|
|
14
16
|
import { loadPages, loadStore } from './discover.js'
|
|
15
17
|
import * as log from './logger.js'
|
|
@@ -31,6 +33,14 @@ const ROOT = rootArg !== -1
|
|
|
31
33
|
// resolve to the project root, not wherever the parent process was launched from.
|
|
32
34
|
if (process.cwd() !== ROOT) process.chdir(ROOT)
|
|
33
35
|
|
|
36
|
+
// Hot reload re-imports each page with a cache-busting stamp; this hook passes the stamp on
|
|
37
|
+
// to the project modules the page imports, so editing src/lib or src/components takes
|
|
38
|
+
// effect too (see reload-hooks.js). realpath: Node reports resolved URLs without symlinks.
|
|
39
|
+
register('./reload-hooks.js', {
|
|
40
|
+
parentURL: import.meta.url,
|
|
41
|
+
data: { rootUrl: pathToFileURL(fs.realpathSync(ROOT)).href + '/' },
|
|
42
|
+
})
|
|
43
|
+
|
|
34
44
|
let _config = {}
|
|
35
45
|
const configPath = path.join(ROOT, 'pulse.config.js')
|
|
36
46
|
if (fs.existsSync(configPath)) {
|
package/src/cli/discover.js
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
import fs from 'fs'
|
|
16
16
|
import path from 'path'
|
|
17
|
+
import { pathToFileURL } from 'url'
|
|
17
18
|
|
|
18
19
|
/**
|
|
19
20
|
* Derive a route from a file path relative to the pages directory.
|
|
@@ -136,7 +137,7 @@ export async function loadStore(projectRoot, cacheBust = null) {
|
|
|
136
137
|
const storePath = path.join(projectRoot, 'pulse.store.js')
|
|
137
138
|
if (!fs.existsSync(storePath)) return null
|
|
138
139
|
|
|
139
|
-
const url =
|
|
140
|
+
const url = pathToFileURL(storePath).href + (cacheBust ? `?t=${cacheBust}` : '')
|
|
140
141
|
const mod = await import(url)
|
|
141
142
|
const def = mod.default
|
|
142
143
|
if (!def || typeof def !== 'object') {
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pulse — module-loader hook for dev hot reload
|
|
3
|
+
*
|
|
4
|
+
* `pulse dev` re-imports each page with `?t=<stamp>` to dodge Node's ESM cache, but that
|
|
5
|
+
* only refreshes the page file: everything the page imports (src/lib, src/components, ...)
|
|
6
|
+
* resolves to the same URL as before and comes back stale from the cache. This hook gives
|
|
7
|
+
* a project module imported by a stamped module the same stamp, so the whole project
|
|
8
|
+
* graph is re-evaluated on a reload.
|
|
9
|
+
*
|
|
10
|
+
* Only the project's own files are stamped. Anything in node_modules, the framework
|
|
11
|
+
* itself, and `node:` builtins keep their URL, so packages (and framework singletons)
|
|
12
|
+
* are evaluated once rather than once per edit.
|
|
13
|
+
*
|
|
14
|
+
* Limits: CommonJS files (.cjs) are cached by path, so the stamp cannot refresh them, and
|
|
15
|
+
* modules outside the project root (e.g. a sibling workspace package) are neither stamped
|
|
16
|
+
* nor watched.
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
let rootUrl = ''
|
|
20
|
+
|
|
21
|
+
export function initialize(data) {
|
|
22
|
+
rootUrl = data.rootUrl
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export async function resolve(specifier, context, nextResolve) {
|
|
26
|
+
const result = await nextResolve(specifier, context)
|
|
27
|
+
const url = result.url
|
|
28
|
+
if (!rootUrl || !url.startsWith(rootUrl) || url.includes('?')) return result
|
|
29
|
+
if (url.slice(rootUrl.length).includes('node_modules/')) return result // below the root: a project may itself live under a node_modules folder
|
|
30
|
+
if (!context.parentURL?.startsWith(rootUrl)) return result
|
|
31
|
+
|
|
32
|
+
const stamp = new URL(context.parentURL).searchParams.get('t')
|
|
33
|
+
if (!stamp || !/^\d+$/.test(stamp)) return result
|
|
34
|
+
return { ...result, url: `${url}?t=${stamp}` }
|
|
35
|
+
}
|