@hedystia/view 2.1.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/constants.cjs +13 -0
- package/dist/constants.cjs.map +1 -0
- package/dist/constants.mjs +13 -0
- package/dist/constants.mjs.map +1 -0
- package/dist/context/context.cjs +51 -0
- package/dist/context/context.cjs.map +1 -0
- package/dist/context/context.d.cts +25 -0
- package/dist/context/context.d.mts +25 -0
- package/dist/context/context.mjs +50 -0
- package/dist/context/context.mjs.map +1 -0
- package/dist/fetch/resource.cjs +89 -0
- package/dist/fetch/resource.cjs.map +1 -0
- package/dist/fetch/resource.d.cts +14 -0
- package/dist/fetch/resource.d.mts +14 -0
- package/dist/fetch/resource.mjs +88 -0
- package/dist/fetch/resource.mjs.map +1 -0
- package/dist/index.cjs +58 -0
- package/dist/index.d.cts +15 -0
- package/dist/index.d.mts +15 -0
- package/dist/index.mjs +14 -0
- package/dist/jsx/element.cjs +201 -0
- package/dist/jsx/element.cjs.map +1 -0
- package/dist/jsx/element.d.cts +48 -0
- package/dist/jsx/element.d.mts +48 -0
- package/dist/jsx/element.mjs +199 -0
- package/dist/jsx/element.mjs.map +1 -0
- package/dist/jsx-dev-runtime.cjs +40 -0
- package/dist/jsx-dev-runtime.cjs.map +1 -0
- package/dist/jsx-dev-runtime.d.cts +21 -0
- package/dist/jsx-dev-runtime.d.mts +21 -0
- package/dist/jsx-dev-runtime.mjs +36 -0
- package/dist/jsx-dev-runtime.mjs.map +1 -0
- package/dist/jsx-runtime.cjs +5 -0
- package/dist/jsx-runtime.d.cts +3 -0
- package/dist/jsx-runtime.d.mts +3 -0
- package/dist/jsx-runtime.mjs +2 -0
- package/dist/jsx.d.cts +942 -0
- package/dist/jsx.d.mts +942 -0
- package/dist/lifecycle/hooks.cjs +56 -0
- package/dist/lifecycle/hooks.cjs.map +1 -0
- package/dist/lifecycle/hooks.d.cts +37 -0
- package/dist/lifecycle/hooks.d.mts +37 -0
- package/dist/lifecycle/hooks.mjs +54 -0
- package/dist/lifecycle/hooks.mjs.map +1 -0
- package/dist/render/engine.cjs +52 -0
- package/dist/render/engine.cjs.map +1 -0
- package/dist/render/engine.d.cts +31 -0
- package/dist/render/engine.d.mts +31 -0
- package/dist/render/engine.mjs +51 -0
- package/dist/render/engine.mjs.map +1 -0
- package/dist/render/flow.cjs +286 -0
- package/dist/render/flow.cjs.map +1 -0
- package/dist/render/flow.d.cts +64 -0
- package/dist/render/flow.d.mts +64 -0
- package/dist/render/flow.mjs +279 -0
- package/dist/render/flow.mjs.map +1 -0
- package/dist/scheduler/scheduler.cjs +61 -0
- package/dist/scheduler/scheduler.cjs.map +1 -0
- package/dist/scheduler/scheduler.d.cts +31 -0
- package/dist/scheduler/scheduler.d.mts +31 -0
- package/dist/scheduler/scheduler.mjs +59 -0
- package/dist/scheduler/scheduler.mjs.map +1 -0
- package/dist/signal/signal.cjs +387 -0
- package/dist/signal/signal.cjs.map +1 -0
- package/dist/signal/signal.d.cts +44 -0
- package/dist/signal/signal.d.mts +44 -0
- package/dist/signal/signal.mjs +370 -0
- package/dist/signal/signal.mjs.map +1 -0
- package/dist/store/index.cjs +1 -0
- package/dist/store/index.mjs +2 -0
- package/dist/store/store.cjs +94 -0
- package/dist/store/store.cjs.map +1 -0
- package/dist/store/store.d.cts +22 -0
- package/dist/store/store.d.mts +22 -0
- package/dist/store/store.mjs +91 -0
- package/dist/store/store.mjs.map +1 -0
- package/dist/style/computed.cjs +65 -0
- package/dist/style/computed.cjs.map +1 -0
- package/dist/style/computed.d.cts +18 -0
- package/dist/style/computed.d.mts +18 -0
- package/dist/style/computed.mjs +63 -0
- package/dist/style/computed.mjs.map +1 -0
- package/dist/text/text.cjs +74 -0
- package/dist/text/text.cjs.map +1 -0
- package/dist/text/text.d.cts +31 -0
- package/dist/text/text.d.mts +31 -0
- package/dist/text/text.mjs +72 -0
- package/dist/text/text.mjs.map +1 -0
- package/dist/types.d.cts +185 -0
- package/dist/types.d.mts +185 -0
- package/dist/utils/index.cjs +34 -0
- package/dist/utils/index.cjs.map +1 -0
- package/dist/utils/index.mjs +33 -0
- package/dist/utils/index.mjs.map +1 -0
- package/dist/watch/watcher.cjs +71 -0
- package/dist/watch/watcher.cjs.map +1 -0
- package/dist/watch/watcher.d.cts +17 -0
- package/dist/watch/watcher.d.mts +17 -0
- package/dist/watch/watcher.mjs +70 -0
- package/dist/watch/watcher.mjs.map +1 -0
- package/package.json +34 -0
- package/readme.md +395 -0
package/dist/types.d.mts
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { JSX } from "./jsx.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/types.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Function that returns a value of type T - used for reactive accessors
|
|
6
|
+
*/
|
|
7
|
+
type Accessor<T> = () => T;
|
|
8
|
+
/**
|
|
9
|
+
* Mutable reactive signal holding a value of type T
|
|
10
|
+
*/
|
|
11
|
+
interface Signal<T> {
|
|
12
|
+
/** @internal */
|
|
13
|
+
_value: T;
|
|
14
|
+
/** @internal */
|
|
15
|
+
_observers: Computation<any>[] | null;
|
|
16
|
+
/** @internal */
|
|
17
|
+
_observerSlots: number[] | null;
|
|
18
|
+
/** @internal */
|
|
19
|
+
_comparator?: (prev: T, next: T) => boolean;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Read-only derived reactive signal computed from other signals
|
|
23
|
+
*/
|
|
24
|
+
interface Computed<T> {
|
|
25
|
+
/** @internal */
|
|
26
|
+
_value: T;
|
|
27
|
+
/** @internal */
|
|
28
|
+
_fn: () => T;
|
|
29
|
+
/** @internal */
|
|
30
|
+
_observers: Computation<any>[] | null;
|
|
31
|
+
/** @internal */
|
|
32
|
+
_observerSlots: number[] | null;
|
|
33
|
+
/** @internal */
|
|
34
|
+
_sources: Signal<any>[] | null;
|
|
35
|
+
/** @internal */
|
|
36
|
+
_sourceSlots: number[] | null;
|
|
37
|
+
/** @internal */
|
|
38
|
+
_comparator?: (prev: T, next: T) => boolean;
|
|
39
|
+
/** @internal */
|
|
40
|
+
_state: 0 | 1 | 2;
|
|
41
|
+
/** Call to get the current value */
|
|
42
|
+
(): T;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Union type for reading signal values
|
|
46
|
+
*/
|
|
47
|
+
type ReadonlySignal<T> = Signal<T> | Computed<T>;
|
|
48
|
+
/**
|
|
49
|
+
* Internal computation node in the reactive graph
|
|
50
|
+
*/
|
|
51
|
+
interface Computation<T> {
|
|
52
|
+
/** @internal */
|
|
53
|
+
_fn: EffectFunction<T>;
|
|
54
|
+
/** @internal */
|
|
55
|
+
_value: T | undefined;
|
|
56
|
+
/** @internal */
|
|
57
|
+
_sources: Signal<any>[] | null;
|
|
58
|
+
/** @internal */
|
|
59
|
+
_sourceSlots: number[] | null;
|
|
60
|
+
/** @internal */
|
|
61
|
+
_observers: Computation<any>[] | null;
|
|
62
|
+
/** @internal */
|
|
63
|
+
_observerSlots: number[] | null;
|
|
64
|
+
/** @internal */
|
|
65
|
+
_owner: Owner | null;
|
|
66
|
+
/** @internal */
|
|
67
|
+
_cleanups: (() => void)[] | null;
|
|
68
|
+
/** @internal */
|
|
69
|
+
_context: any | null;
|
|
70
|
+
/** @internal */
|
|
71
|
+
_suspense: SuspenseContextType | null;
|
|
72
|
+
/** @internal */
|
|
73
|
+
_user: boolean;
|
|
74
|
+
/** @internal */
|
|
75
|
+
_pure: boolean;
|
|
76
|
+
/** @internal */
|
|
77
|
+
_state: 0 | 1 | 2;
|
|
78
|
+
/** @internal */
|
|
79
|
+
_updatedAt: number | null;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Reactive owner/context node
|
|
83
|
+
*/
|
|
84
|
+
interface Owner {
|
|
85
|
+
/** @internal */
|
|
86
|
+
_owned: Computation<any>[] | null;
|
|
87
|
+
/** @internal */
|
|
88
|
+
_cleanups: (() => void)[] | null;
|
|
89
|
+
/** @internal */
|
|
90
|
+
_owner: Owner | null;
|
|
91
|
+
/** @internal */
|
|
92
|
+
_context: any | null;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Effect function type for computations
|
|
96
|
+
*/
|
|
97
|
+
type EffectFunction<T> = (prev?: T) => T;
|
|
98
|
+
/**
|
|
99
|
+
* Options for creating a signal
|
|
100
|
+
*/
|
|
101
|
+
interface SignalOptions<T> {
|
|
102
|
+
equals?: false | ((prev: T, next: T) => boolean);
|
|
103
|
+
name?: string;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Component function type
|
|
107
|
+
*/
|
|
108
|
+
type Component<P extends Record<string, any> = {}> = (props: P) => JSX.Element;
|
|
109
|
+
/**
|
|
110
|
+
* Component that accepts children
|
|
111
|
+
*/
|
|
112
|
+
type ParentComponent<P extends Record<string, any> = {}> = Component<P & {
|
|
113
|
+
children?: JSX.Children;
|
|
114
|
+
}>;
|
|
115
|
+
/**
|
|
116
|
+
* Component that requires children
|
|
117
|
+
*/
|
|
118
|
+
type FlowComponent<P extends Record<string, any> = {}, C = JSX.Children> = Component<P & {
|
|
119
|
+
children: C;
|
|
120
|
+
}>;
|
|
121
|
+
/**
|
|
122
|
+
* Context object for provider/consumer pattern
|
|
123
|
+
*/
|
|
124
|
+
interface Context<T> {
|
|
125
|
+
_id: symbol;
|
|
126
|
+
_defaultValue: T | undefined;
|
|
127
|
+
Provider: Component<{
|
|
128
|
+
value: T;
|
|
129
|
+
children: JSX.Element;
|
|
130
|
+
}>;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Suspense context type for error boundaries and suspense
|
|
134
|
+
*/
|
|
135
|
+
interface SuspenseContextType {
|
|
136
|
+
increment: () => void;
|
|
137
|
+
decrement: () => void;
|
|
138
|
+
resolved: boolean;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Resource object returned by load()
|
|
142
|
+
*/
|
|
143
|
+
interface Resource<T> {
|
|
144
|
+
(): T | undefined;
|
|
145
|
+
readonly state: Signal<"unresolved" | "pending" | "ready" | "refreshing" | "errored">;
|
|
146
|
+
readonly loading: Signal<boolean>;
|
|
147
|
+
readonly error: Signal<Error | undefined>;
|
|
148
|
+
readonly data: Signal<T | undefined>;
|
|
149
|
+
readonly ready: boolean;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Action object for mutations
|
|
153
|
+
*/
|
|
154
|
+
interface Action<T, A> {
|
|
155
|
+
(args: A): Promise<T>;
|
|
156
|
+
run: (args: A) => Promise<T>;
|
|
157
|
+
readonly loading: Signal<boolean>;
|
|
158
|
+
readonly error: Signal<Error | undefined>;
|
|
159
|
+
readonly data: Signal<T | undefined>;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Style properties type
|
|
163
|
+
*/
|
|
164
|
+
type StyleProps = Record<string, string | number | Accessor<string | number> | undefined>;
|
|
165
|
+
/**
|
|
166
|
+
* Computed style object
|
|
167
|
+
*/
|
|
168
|
+
type ComputedStyle<T extends StyleProps> = () => T;
|
|
169
|
+
/**
|
|
170
|
+
* Store value types
|
|
171
|
+
*/
|
|
172
|
+
type StoreValue = string | number | boolean | null | undefined | object | StoreValue[];
|
|
173
|
+
/**
|
|
174
|
+
* Store node type for nested access
|
|
175
|
+
*/
|
|
176
|
+
type StoreNode<T> = T extends object ? Record<keyof T, StoreNode<T[keyof T]>> : Signal<T>;
|
|
177
|
+
/**
|
|
178
|
+
* Store object
|
|
179
|
+
*/
|
|
180
|
+
interface Store<T extends Record<string, StoreValue>> {
|
|
181
|
+
[key: string]: StoreNode<T[string]>;
|
|
182
|
+
}
|
|
183
|
+
//#endregion
|
|
184
|
+
export { Accessor, Action, Component, Computed, ComputedStyle, Context, FlowComponent, Owner, ParentComponent, ReadonlySignal, Resource, Signal, SignalOptions, Store, StoreNode, StoreValue, StyleProps };
|
|
185
|
+
//# sourceMappingURL=types.d.mts.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
//#region src/utils/index.ts
|
|
2
|
+
/**
|
|
3
|
+
* Internal utilities for @hedystia/view
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Equality comparison function for signals
|
|
7
|
+
*/
|
|
8
|
+
function equalFn(a, b) {
|
|
9
|
+
return a === b;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Creates a shallow clone of an object
|
|
13
|
+
*/
|
|
14
|
+
function shallowClone(obj) {
|
|
15
|
+
const target = {};
|
|
16
|
+
for (const key in obj) if (Object.hasOwn(obj, key)) target[key] = obj[key];
|
|
17
|
+
return target;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Merges two style objects, with the second taking precedence
|
|
21
|
+
*/
|
|
22
|
+
function mergeStyles(base, override) {
|
|
23
|
+
const result = shallowClone(base);
|
|
24
|
+
for (const key in override) if (Object.hasOwn(override, key)) {
|
|
25
|
+
const value = override[key];
|
|
26
|
+
if (value !== void 0) result[key] = value;
|
|
27
|
+
}
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
exports.equalFn = equalFn;
|
|
32
|
+
exports.mergeStyles = mergeStyles;
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":[],"sources":["../../src/utils/index.ts"],"sourcesContent":["/**\n * Internal utilities for @hedystia/view\n */\n\n/**\n * Equality comparison function for signals\n */\nexport function equalFn<T>(a: T, b: T): boolean {\n return a === b;\n}\n\n/**\n * Creates a shallow clone of an object\n */\nexport function shallowClone<T extends object>(obj: T): T {\n const target = {} as any;\n for (const key in obj) {\n if (Object.hasOwn(obj, key)) {\n target[key] = obj[key];\n }\n }\n return target;\n}\n\n/**\n * Merges two style objects, with the second taking precedence\n */\nexport function mergeStyles(\n base: Record<string, any>,\n override: Record<string, any>,\n): Record<string, any> {\n const result = shallowClone(base);\n for (const key in override) {\n if (Object.hasOwn(override, key)) {\n const value = override[key];\n if (value !== undefined) {\n result[key] = value;\n }\n }\n }\n return result;\n}\n\n/**\n * Checks if a value is a function\n */\nexport function isFunction(value: unknown): value is Function {\n return typeof value === \"function\";\n}\n\n/**\n * Checks if a value is an object (not null)\n */\nexport function isObject(value: unknown): value is object {\n return typeof value === \"object\" && value !== null;\n}\n\n/**\n * No-op function\n */\nexport function noop(): void {}\n"],"mappings":";;;;;;;AAOA,SAAgB,QAAW,GAAM,GAAe;AAC9C,QAAO,MAAM;;;;;AAMf,SAAgB,aAA+B,KAAW;CACxD,MAAM,SAAS,EAAE;AACjB,MAAK,MAAM,OAAO,IAChB,KAAI,OAAO,OAAO,KAAK,IAAI,CACzB,QAAO,OAAO,IAAI;AAGtB,QAAO;;;;;AAMT,SAAgB,YACd,MACA,UACqB;CACrB,MAAM,SAAS,aAAa,KAAK;AACjC,MAAK,MAAM,OAAO,SAChB,KAAI,OAAO,OAAO,UAAU,IAAI,EAAE;EAChC,MAAM,QAAQ,SAAS;AACvB,MAAI,UAAU,KAAA,EACZ,QAAO,OAAO;;AAIpB,QAAO"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
//#region src/utils/index.ts
|
|
2
|
+
/**
|
|
3
|
+
* Internal utilities for @hedystia/view
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Equality comparison function for signals
|
|
7
|
+
*/
|
|
8
|
+
function equalFn(a, b) {
|
|
9
|
+
return a === b;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Creates a shallow clone of an object
|
|
13
|
+
*/
|
|
14
|
+
function shallowClone(obj) {
|
|
15
|
+
const target = {};
|
|
16
|
+
for (const key in obj) if (Object.hasOwn(obj, key)) target[key] = obj[key];
|
|
17
|
+
return target;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Merges two style objects, with the second taking precedence
|
|
21
|
+
*/
|
|
22
|
+
function mergeStyles(base, override) {
|
|
23
|
+
const result = shallowClone(base);
|
|
24
|
+
for (const key in override) if (Object.hasOwn(override, key)) {
|
|
25
|
+
const value = override[key];
|
|
26
|
+
if (value !== void 0) result[key] = value;
|
|
27
|
+
}
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
export { equalFn, mergeStyles };
|
|
32
|
+
|
|
33
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/utils/index.ts"],"sourcesContent":["/**\n * Internal utilities for @hedystia/view\n */\n\n/**\n * Equality comparison function for signals\n */\nexport function equalFn<T>(a: T, b: T): boolean {\n return a === b;\n}\n\n/**\n * Creates a shallow clone of an object\n */\nexport function shallowClone<T extends object>(obj: T): T {\n const target = {} as any;\n for (const key in obj) {\n if (Object.hasOwn(obj, key)) {\n target[key] = obj[key];\n }\n }\n return target;\n}\n\n/**\n * Merges two style objects, with the second taking precedence\n */\nexport function mergeStyles(\n base: Record<string, any>,\n override: Record<string, any>,\n): Record<string, any> {\n const result = shallowClone(base);\n for (const key in override) {\n if (Object.hasOwn(override, key)) {\n const value = override[key];\n if (value !== undefined) {\n result[key] = value;\n }\n }\n }\n return result;\n}\n\n/**\n * Checks if a value is a function\n */\nexport function isFunction(value: unknown): value is Function {\n return typeof value === \"function\";\n}\n\n/**\n * Checks if a value is an object (not null)\n */\nexport function isObject(value: unknown): value is object {\n return typeof value === \"object\" && value !== null;\n}\n\n/**\n * No-op function\n */\nexport function noop(): void {}\n"],"mappings":";;;;;;;AAOA,SAAgB,QAAW,GAAM,GAAe;AAC9C,QAAO,MAAM;;;;;AAMf,SAAgB,aAA+B,KAAW;CACxD,MAAM,SAAS,EAAE;AACjB,MAAK,MAAM,OAAO,IAChB,KAAI,OAAO,OAAO,KAAK,IAAI,CACzB,QAAO,OAAO,IAAI;AAGtB,QAAO;;;;;AAMT,SAAgB,YACd,MACA,UACqB;CACrB,MAAM,SAAS,aAAa,KAAK;AACjC,MAAK,MAAM,OAAO,SAChB,KAAI,OAAO,OAAO,UAAU,IAAI,EAAE;EAChC,MAAM,QAAQ,SAAS;AACvB,MAAI,UAAU,KAAA,EACZ,QAAO,OAAO;;AAIpB,QAAO"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
const require_signal = require("../signal/signal.cjs");
|
|
2
|
+
//#region src/watch/watcher.ts
|
|
3
|
+
/**
|
|
4
|
+
* Watchers and reactive effects for @hedystia/view
|
|
5
|
+
*
|
|
6
|
+
* Provides effect tracking and reactive subscriptions.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Create a reactive effect that runs when dependencies change
|
|
10
|
+
*/
|
|
11
|
+
function on(track, run) {
|
|
12
|
+
let cleanup;
|
|
13
|
+
let prevValue;
|
|
14
|
+
let hasRun = false;
|
|
15
|
+
let stopped = false;
|
|
16
|
+
const computation = {
|
|
17
|
+
_fn: () => {
|
|
18
|
+
if (stopped) return;
|
|
19
|
+
const value = track();
|
|
20
|
+
require_signal.untrack(() => {
|
|
21
|
+
if (cleanup) {
|
|
22
|
+
cleanup();
|
|
23
|
+
cleanup = void 0;
|
|
24
|
+
}
|
|
25
|
+
const result = run(value, hasRun ? prevValue : value);
|
|
26
|
+
if (typeof result === "function") cleanup = result;
|
|
27
|
+
});
|
|
28
|
+
prevValue = value;
|
|
29
|
+
hasRun = true;
|
|
30
|
+
},
|
|
31
|
+
_value: void 0,
|
|
32
|
+
_sources: null,
|
|
33
|
+
_sourceSlots: null,
|
|
34
|
+
_observers: null,
|
|
35
|
+
_observerSlots: null,
|
|
36
|
+
_owner: require_signal.Owner,
|
|
37
|
+
_cleanups: null,
|
|
38
|
+
_context: null,
|
|
39
|
+
_suspense: null,
|
|
40
|
+
_user: true,
|
|
41
|
+
_pure: false,
|
|
42
|
+
_state: 0,
|
|
43
|
+
_updatedAt: null
|
|
44
|
+
};
|
|
45
|
+
require_signal.runComputation(computation);
|
|
46
|
+
return () => {
|
|
47
|
+
stopped = true;
|
|
48
|
+
require_signal.cleanupSources(computation);
|
|
49
|
+
if (cleanup) {
|
|
50
|
+
cleanup();
|
|
51
|
+
cleanup = void 0;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Create a one-time effect that runs once and disposes
|
|
57
|
+
*/
|
|
58
|
+
function once(track, run) {
|
|
59
|
+
let hasRun = false;
|
|
60
|
+
return on(track, (value) => {
|
|
61
|
+
if (!hasRun) {
|
|
62
|
+
hasRun = true;
|
|
63
|
+
run(value);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
//#endregion
|
|
68
|
+
exports.on = on;
|
|
69
|
+
exports.once = once;
|
|
70
|
+
|
|
71
|
+
//# sourceMappingURL=watcher.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher.cjs","names":["Owner"],"sources":["../../src/watch/watcher.ts"],"sourcesContent":["/**\n * Watchers and reactive effects for @hedystia/view\n *\n * Provides effect tracking and reactive subscriptions.\n */\n\nimport { cleanupSources, Owner, runComputation, untrack } from \"../signal\";\nimport type { Computation } from \"../types\";\n\n/**\n * Create a reactive effect that runs when dependencies change\n */\nexport function on<T>(track: () => T, run: (value: T, prev: T) => any | (() => void)): () => void {\n let cleanup: (() => void) | undefined;\n let prevValue: T | undefined;\n let hasRun = false;\n let stopped = false;\n\n const computation: Computation<any> = {\n _fn: () => {\n if (stopped) {\n return undefined;\n }\n\n // Track dependencies from the track function\n const value = track();\n\n // Run callback untracked so reads inside run() don't become dependencies\n untrack(() => {\n if (cleanup) {\n cleanup();\n cleanup = undefined;\n }\n\n const result = run(value, hasRun ? prevValue! : value);\n if (typeof result === \"function\") {\n cleanup = result;\n }\n });\n\n prevValue = value;\n hasRun = true;\n return undefined;\n },\n _value: undefined,\n _sources: null,\n _sourceSlots: null,\n _observers: null,\n _observerSlots: null,\n _owner: Owner,\n _cleanups: null,\n _context: null,\n _suspense: null,\n _user: true,\n _pure: false,\n _state: 0,\n _updatedAt: null,\n };\n\n // Run initial execution with proper Listener tracking\n runComputation(computation);\n\n return () => {\n stopped = true;\n cleanupSources(computation);\n if (cleanup) {\n cleanup();\n cleanup = undefined;\n }\n };\n}\n\n/**\n * Create a one-time effect that runs once and disposes\n */\nexport function once<T>(track: () => T, run: (value: T) => void): () => void {\n let hasRun = false;\n return on(track, (value) => {\n if (!hasRun) {\n hasRun = true;\n run(value);\n }\n });\n}\n"],"mappings":";;;;;;;;;;AAYA,SAAgB,GAAM,OAAgB,KAA4D;CAChG,IAAI;CACJ,IAAI;CACJ,IAAI,SAAS;CACb,IAAI,UAAU;CAEd,MAAM,cAAgC;EACpC,WAAW;AACT,OAAI,QACF;GAIF,MAAM,QAAQ,OAAO;AAGrB,kBAAA,cAAc;AACZ,QAAI,SAAS;AACX,cAAS;AACT,eAAU,KAAA;;IAGZ,MAAM,SAAS,IAAI,OAAO,SAAS,YAAa,MAAM;AACtD,QAAI,OAAO,WAAW,WACpB,WAAU;KAEZ;AAEF,eAAY;AACZ,YAAS;;EAGX,QAAQ,KAAA;EACR,UAAU;EACV,cAAc;EACd,YAAY;EACZ,gBAAgB;EAChB,QAAQA,eAAAA;EACR,WAAW;EACX,UAAU;EACV,WAAW;EACX,OAAO;EACP,OAAO;EACP,QAAQ;EACR,YAAY;EACb;AAGD,gBAAA,eAAe,YAAY;AAE3B,cAAa;AACX,YAAU;AACV,iBAAA,eAAe,YAAY;AAC3B,MAAI,SAAS;AACX,YAAS;AACT,aAAU,KAAA;;;;;;;AAQhB,SAAgB,KAAQ,OAAgB,KAAqC;CAC3E,IAAI,SAAS;AACb,QAAO,GAAG,QAAQ,UAAU;AAC1B,MAAI,CAAC,QAAQ;AACX,YAAS;AACT,OAAI,MAAM;;GAEZ"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//#region src/watch/watcher.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Watchers and reactive effects for @hedystia/view
|
|
4
|
+
*
|
|
5
|
+
* Provides effect tracking and reactive subscriptions.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Create a reactive effect that runs when dependencies change
|
|
9
|
+
*/
|
|
10
|
+
declare function on<T>(track: () => T, run: (value: T, prev: T) => any | (() => void)): () => void;
|
|
11
|
+
/**
|
|
12
|
+
* Create a one-time effect that runs once and disposes
|
|
13
|
+
*/
|
|
14
|
+
declare function once<T>(track: () => T, run: (value: T) => void): () => void;
|
|
15
|
+
//#endregion
|
|
16
|
+
export { on, once };
|
|
17
|
+
//# sourceMappingURL=watcher.d.cts.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//#region src/watch/watcher.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Watchers and reactive effects for @hedystia/view
|
|
4
|
+
*
|
|
5
|
+
* Provides effect tracking and reactive subscriptions.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Create a reactive effect that runs when dependencies change
|
|
9
|
+
*/
|
|
10
|
+
declare function on<T>(track: () => T, run: (value: T, prev: T) => any | (() => void)): () => void;
|
|
11
|
+
/**
|
|
12
|
+
* Create a one-time effect that runs once and disposes
|
|
13
|
+
*/
|
|
14
|
+
declare function once<T>(track: () => T, run: (value: T) => void): () => void;
|
|
15
|
+
//#endregion
|
|
16
|
+
export { on, once };
|
|
17
|
+
//# sourceMappingURL=watcher.d.mts.map
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { Owner, cleanupSources, runComputation, untrack } from "../signal/signal.mjs";
|
|
2
|
+
//#region src/watch/watcher.ts
|
|
3
|
+
/**
|
|
4
|
+
* Watchers and reactive effects for @hedystia/view
|
|
5
|
+
*
|
|
6
|
+
* Provides effect tracking and reactive subscriptions.
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Create a reactive effect that runs when dependencies change
|
|
10
|
+
*/
|
|
11
|
+
function on(track, run) {
|
|
12
|
+
let cleanup;
|
|
13
|
+
let prevValue;
|
|
14
|
+
let hasRun = false;
|
|
15
|
+
let stopped = false;
|
|
16
|
+
const computation = {
|
|
17
|
+
_fn: () => {
|
|
18
|
+
if (stopped) return;
|
|
19
|
+
const value = track();
|
|
20
|
+
untrack(() => {
|
|
21
|
+
if (cleanup) {
|
|
22
|
+
cleanup();
|
|
23
|
+
cleanup = void 0;
|
|
24
|
+
}
|
|
25
|
+
const result = run(value, hasRun ? prevValue : value);
|
|
26
|
+
if (typeof result === "function") cleanup = result;
|
|
27
|
+
});
|
|
28
|
+
prevValue = value;
|
|
29
|
+
hasRun = true;
|
|
30
|
+
},
|
|
31
|
+
_value: void 0,
|
|
32
|
+
_sources: null,
|
|
33
|
+
_sourceSlots: null,
|
|
34
|
+
_observers: null,
|
|
35
|
+
_observerSlots: null,
|
|
36
|
+
_owner: Owner,
|
|
37
|
+
_cleanups: null,
|
|
38
|
+
_context: null,
|
|
39
|
+
_suspense: null,
|
|
40
|
+
_user: true,
|
|
41
|
+
_pure: false,
|
|
42
|
+
_state: 0,
|
|
43
|
+
_updatedAt: null
|
|
44
|
+
};
|
|
45
|
+
runComputation(computation);
|
|
46
|
+
return () => {
|
|
47
|
+
stopped = true;
|
|
48
|
+
cleanupSources(computation);
|
|
49
|
+
if (cleanup) {
|
|
50
|
+
cleanup();
|
|
51
|
+
cleanup = void 0;
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Create a one-time effect that runs once and disposes
|
|
57
|
+
*/
|
|
58
|
+
function once(track, run) {
|
|
59
|
+
let hasRun = false;
|
|
60
|
+
return on(track, (value) => {
|
|
61
|
+
if (!hasRun) {
|
|
62
|
+
hasRun = true;
|
|
63
|
+
run(value);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
//#endregion
|
|
68
|
+
export { on, once };
|
|
69
|
+
|
|
70
|
+
//# sourceMappingURL=watcher.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"watcher.mjs","names":[],"sources":["../../src/watch/watcher.ts"],"sourcesContent":["/**\n * Watchers and reactive effects for @hedystia/view\n *\n * Provides effect tracking and reactive subscriptions.\n */\n\nimport { cleanupSources, Owner, runComputation, untrack } from \"../signal\";\nimport type { Computation } from \"../types\";\n\n/**\n * Create a reactive effect that runs when dependencies change\n */\nexport function on<T>(track: () => T, run: (value: T, prev: T) => any | (() => void)): () => void {\n let cleanup: (() => void) | undefined;\n let prevValue: T | undefined;\n let hasRun = false;\n let stopped = false;\n\n const computation: Computation<any> = {\n _fn: () => {\n if (stopped) {\n return undefined;\n }\n\n // Track dependencies from the track function\n const value = track();\n\n // Run callback untracked so reads inside run() don't become dependencies\n untrack(() => {\n if (cleanup) {\n cleanup();\n cleanup = undefined;\n }\n\n const result = run(value, hasRun ? prevValue! : value);\n if (typeof result === \"function\") {\n cleanup = result;\n }\n });\n\n prevValue = value;\n hasRun = true;\n return undefined;\n },\n _value: undefined,\n _sources: null,\n _sourceSlots: null,\n _observers: null,\n _observerSlots: null,\n _owner: Owner,\n _cleanups: null,\n _context: null,\n _suspense: null,\n _user: true,\n _pure: false,\n _state: 0,\n _updatedAt: null,\n };\n\n // Run initial execution with proper Listener tracking\n runComputation(computation);\n\n return () => {\n stopped = true;\n cleanupSources(computation);\n if (cleanup) {\n cleanup();\n cleanup = undefined;\n }\n };\n}\n\n/**\n * Create a one-time effect that runs once and disposes\n */\nexport function once<T>(track: () => T, run: (value: T) => void): () => void {\n let hasRun = false;\n return on(track, (value) => {\n if (!hasRun) {\n hasRun = true;\n run(value);\n }\n });\n}\n"],"mappings":";;;;;;;;;;AAYA,SAAgB,GAAM,OAAgB,KAA4D;CAChG,IAAI;CACJ,IAAI;CACJ,IAAI,SAAS;CACb,IAAI,UAAU;CAEd,MAAM,cAAgC;EACpC,WAAW;AACT,OAAI,QACF;GAIF,MAAM,QAAQ,OAAO;AAGrB,iBAAc;AACZ,QAAI,SAAS;AACX,cAAS;AACT,eAAU,KAAA;;IAGZ,MAAM,SAAS,IAAI,OAAO,SAAS,YAAa,MAAM;AACtD,QAAI,OAAO,WAAW,WACpB,WAAU;KAEZ;AAEF,eAAY;AACZ,YAAS;;EAGX,QAAQ,KAAA;EACR,UAAU;EACV,cAAc;EACd,YAAY;EACZ,gBAAgB;EAChB,QAAQ;EACR,WAAW;EACX,UAAU;EACV,WAAW;EACX,OAAO;EACP,OAAO;EACP,QAAQ;EACR,YAAY;EACb;AAGD,gBAAe,YAAY;AAE3B,cAAa;AACX,YAAU;AACV,iBAAe,YAAY;AAC3B,MAAI,SAAS;AACX,YAAS;AACT,aAAU,KAAA;;;;;;;AAQhB,SAAgB,KAAQ,OAAgB,KAAqC;CAC3E,IAAI,SAAS;AACb,QAAO,GAAG,QAAQ,UAAU;AAC1B,MAAI,CAAC,QAAQ;AACX,YAAS;AACT,OAAI,MAAM;;GAEZ"}
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@hedystia/view",
|
|
3
|
+
"version": "2.1.0",
|
|
4
|
+
"description": "Reactive UI engine — fine-grained signals, no Virtual DOM, real DOM nodes",
|
|
5
|
+
"type": "commonjs",
|
|
6
|
+
"types": "./dist/index.d.cts",
|
|
7
|
+
"main": "./dist/index.cjs",
|
|
8
|
+
"module": "./dist/index.mjs",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.cts",
|
|
12
|
+
"import": "./dist/index.mjs",
|
|
13
|
+
"require": "./dist/index.cjs"
|
|
14
|
+
},
|
|
15
|
+
"./jsx-runtime": {
|
|
16
|
+
"types": "./dist/jsx-runtime.d.cts",
|
|
17
|
+
"import": "./dist/jsx-runtime.mjs",
|
|
18
|
+
"require": "./dist/jsx-runtime.cjs"
|
|
19
|
+
},
|
|
20
|
+
"./jsx-dev-runtime": {
|
|
21
|
+
"types": "./dist/jsx-dev-runtime.d.cts",
|
|
22
|
+
"import": "./dist/jsx-dev-runtime.mjs",
|
|
23
|
+
"require": "./dist/jsx-dev-runtime.cjs"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "tsdown --config-loader unrun",
|
|
28
|
+
"release:pkg": "bun publish --provenance --access public",
|
|
29
|
+
"dev": "tsdown --watch"
|
|
30
|
+
},
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"typescript": ">= 6.0.0"
|
|
33
|
+
}
|
|
34
|
+
}
|