jq79 0.5.11 → 0.5.13
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/jq79.cjs +5 -5
- package/dist/jq79.cjs.map +1 -1
- package/dist/jq79.d.ts +1 -1
- package/dist/jq79.global.js +5 -5
- package/dist/jq79.global.js.map +1 -1
- package/dist/jq79.js +5 -5
- package/dist/jq79.js.map +1 -1
- package/dist/reactive.d.ts +1 -0
- package/package.json +3 -1
- package/src/jq79.ts +3 -3
- package/src/reactive.ts +11 -6
package/dist/reactive.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export type ReactiveDeepData<T> = T & {
|
|
|
10
10
|
$effect: (run: () => void, alsoWakenBy?: Record<string, any>[]) => Unsubscribe;
|
|
11
11
|
$dispose: () => void;
|
|
12
12
|
};
|
|
13
|
+
export declare const $toRaw: <T>(value: T) => T;
|
|
13
14
|
export declare const untracked: <T>(fn: () => T) => T;
|
|
14
15
|
export declare const ALSO_WAKEN_BY: unique symbol;
|
|
15
16
|
export declare const $reactive: <T extends Record<string, any>>(data: T) => ReactiveDeepData<T>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jq79",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.13",
|
|
4
4
|
"description": "Mini reactive component library: single-file components, Svelte-style setup scripts, fine-grained proxy reactivity. Single-file build, zero dependencies.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"reactive",
|
|
@@ -64,6 +64,7 @@
|
|
|
64
64
|
"test:coverage": "vitest run --coverage",
|
|
65
65
|
"site": "node scripts/build-site.mjs",
|
|
66
66
|
"site.dev": "node scripts/site-dev.mjs",
|
|
67
|
+
"benchmark": "node scripts/run-benchmark.mjs",
|
|
67
68
|
"prepublishOnly": "npm test && npm run build"
|
|
68
69
|
},
|
|
69
70
|
"peerDependencies": {
|
|
@@ -82,6 +83,7 @@
|
|
|
82
83
|
"jsdom": "^29.1.1",
|
|
83
84
|
"marked": "^18.0.6",
|
|
84
85
|
"marked-highlight": "^2.2.4",
|
|
86
|
+
"playwright": "^1.56.1",
|
|
85
87
|
"sass": "^1.101.0",
|
|
86
88
|
"tsup": "^8.5.1",
|
|
87
89
|
"typescript": "^7.0.2",
|
package/src/jq79.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
|
|
2
2
|
import { $, $$, $create, sanitizeHTML, allowedHosts } from "./dom"
|
|
3
3
|
import type { AllowUrl } from "./dom"
|
|
4
|
-
import { $reactive, untracked, createEffectScope, ALSO_WAKEN_BY } from "./reactive"
|
|
4
|
+
import { $reactive, $toRaw, untracked, createEffectScope, ALSO_WAKEN_BY } from "./reactive"
|
|
5
5
|
import type { ReactiveDeepData, EffectScope } from "./reactive"
|
|
6
6
|
import { transformSetupScript, transformFactoryScript, parsePropsPattern, parseFactoryProps, type PropDecl } from "./transform"
|
|
7
7
|
|
|
8
8
|
export { $, $$, $create } from "./dom"
|
|
9
|
-
export { $reactive } from "./reactive"
|
|
9
|
+
export { $reactive, $toRaw } from "./reactive"
|
|
10
10
|
|
|
11
11
|
// the package version, substituted at build time (tsup/vitest `define`, read
|
|
12
12
|
// from package.json - releases bump it there and nowhere else). The typeof
|
|
@@ -3025,7 +3025,7 @@ export const parseComponent = (component: string): Component79 => new Component7
|
|
|
3025
3025
|
// library helpers injected into setup scripts. They behave like extra
|
|
3026
3026
|
// globals: a same-named scope property (render data or a top-level
|
|
3027
3027
|
// declaration) shadows them
|
|
3028
|
-
const SETUP_HELPERS: Record<string, any> = { $, $$, $create, $reactive, Component79 }
|
|
3028
|
+
const SETUP_HELPERS: Record<string, any> = { $, $$, $create, $reactive, $toRaw, Component79 }
|
|
3029
3029
|
|
|
3030
3030
|
// the hot-reload handshake. jq79/dev serves a classic script that sets the flag
|
|
3031
3031
|
// below; classic scripts run before deferred module ones, so the flag is always
|
package/src/reactive.ts
CHANGED
|
@@ -54,7 +54,12 @@ const pathsOverlap = (a: string, b: string): boolean =>
|
|
|
54
54
|
// what it wraps, the nesting compounds until the process stops responding
|
|
55
55
|
const RAW = Symbol("jq79.raw")
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
// a free function rather than a method on the store, because the store API is
|
|
58
|
+
// served from the root proxy alone (see storeApi): `store.$toRaw()` would work
|
|
59
|
+
// and `store.user.$toRaw()` would not, which is the case callers actually have.
|
|
60
|
+
// The RAW symbol travels on every proxy at every depth, so this works anywhere.
|
|
61
|
+
// What it returns is the real object, not a copy: writes to it notify nobody
|
|
62
|
+
export const $toRaw = <T>(value: T): T => {
|
|
58
63
|
let raw: any = value
|
|
59
64
|
while (raw !== null && typeof raw === "object" && raw[RAW]) raw = raw[RAW]
|
|
60
65
|
return raw
|
|
@@ -173,7 +178,7 @@ export const $reactive = <T extends Record<string, any>>(data: T): ReactiveDeepD
|
|
|
173
178
|
}
|
|
174
179
|
|
|
175
180
|
// the reactive view of `raw`, created on demand. Callers must hand it a raw
|
|
176
|
-
// object (see toRaw at both call sites): wrapping a proxy is what compounds
|
|
181
|
+
// object (see $toRaw at both call sites): wrapping a proxy is what compounds
|
|
177
182
|
const wrap = (raw: Record<string, any>, path: string): Record<string, any> => {
|
|
178
183
|
const cached = proxies.get(raw)
|
|
179
184
|
if (cached) return cached
|
|
@@ -206,7 +211,7 @@ export const $reactive = <T extends Record<string, any>>(data: T): ReactiveDeepD
|
|
|
206
211
|
return value
|
|
207
212
|
}
|
|
208
213
|
|
|
209
|
-
const raw = toRaw(value)
|
|
214
|
+
const raw = $toRaw(value)
|
|
210
215
|
return isWrappable(raw) ? wrap(raw, dotKey) : raw
|
|
211
216
|
},
|
|
212
217
|
set(target, key: string, value, receiver) {
|
|
@@ -226,7 +231,7 @@ export const $reactive = <T extends Record<string, any>>(data: T): ReactiveDeepD
|
|
|
226
231
|
// that `list = [list[1], list[0]]` doesn't write proxies back into the
|
|
227
232
|
// data. Reads re-wrap it, from the cache, as the very same proxy. A
|
|
228
233
|
// whole store assigned in is the exception: it stays as it is
|
|
229
|
-
const stored = isStore(value) ? value : toRaw(value)
|
|
234
|
+
const stored = isStore(value) ? value : $toRaw(value)
|
|
230
235
|
const isNewKey = !Object.prototype.hasOwnProperty.call(target, key)
|
|
231
236
|
// a primitive write that changes nothing notifies nobody: it's what
|
|
232
237
|
// lets an effect write the value it just read (a normalizing
|
|
@@ -269,7 +274,7 @@ export const $reactive = <T extends Record<string, any>>(data: T): ReactiveDeepD
|
|
|
269
274
|
return proxy
|
|
270
275
|
}
|
|
271
276
|
|
|
272
|
-
const reactive = wrap(toRaw(data), "") as ReactiveDeepData<T>
|
|
277
|
+
const reactive = wrap($toRaw(data), "") as ReactiveDeepData<T>
|
|
273
278
|
|
|
274
279
|
// a store handed in with the data (a prop, or render data) is bridged here
|
|
275
280
|
// rather than on first read, so a listener registered before anything reads
|
|
@@ -277,7 +282,7 @@ export const $reactive = <T extends Record<string, any>>(data: T): ReactiveDeepD
|
|
|
277
282
|
// lands, and descending would mean walking whatever else was handed in - a
|
|
278
283
|
// highlighter, an API client - to its leaves. A store sitting deeper is
|
|
279
284
|
// bridged when the read that reaches it wraps its parent
|
|
280
|
-
Object.entries(toRaw(data)).forEach(([key, value]) => {
|
|
285
|
+
Object.entries($toRaw(data)).forEach(([key, value]) => {
|
|
281
286
|
if (isStore(value)) bridge(value, key)
|
|
282
287
|
})
|
|
283
288
|
|