@fictjs/runtime 0.0.2

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 (51) hide show
  1. package/README.md +17 -0
  2. package/dist/index.cjs +4224 -0
  3. package/dist/index.cjs.map +1 -0
  4. package/dist/index.d.cts +1572 -0
  5. package/dist/index.d.ts +1572 -0
  6. package/dist/index.dev.js +4240 -0
  7. package/dist/index.dev.js.map +1 -0
  8. package/dist/index.js +4133 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/jsx-dev-runtime.cjs +44 -0
  11. package/dist/jsx-dev-runtime.cjs.map +1 -0
  12. package/dist/jsx-dev-runtime.js +14 -0
  13. package/dist/jsx-dev-runtime.js.map +1 -0
  14. package/dist/jsx-runtime.cjs +44 -0
  15. package/dist/jsx-runtime.cjs.map +1 -0
  16. package/dist/jsx-runtime.js +14 -0
  17. package/dist/jsx-runtime.js.map +1 -0
  18. package/dist/slim.cjs +3384 -0
  19. package/dist/slim.cjs.map +1 -0
  20. package/dist/slim.d.cts +475 -0
  21. package/dist/slim.d.ts +475 -0
  22. package/dist/slim.js +3335 -0
  23. package/dist/slim.js.map +1 -0
  24. package/package.json +68 -0
  25. package/src/binding.ts +2127 -0
  26. package/src/constants.ts +456 -0
  27. package/src/cycle-guard.ts +134 -0
  28. package/src/devtools.ts +17 -0
  29. package/src/dom.ts +683 -0
  30. package/src/effect.ts +83 -0
  31. package/src/error-boundary.ts +118 -0
  32. package/src/hooks.ts +72 -0
  33. package/src/index.ts +184 -0
  34. package/src/jsx-dev-runtime.ts +2 -0
  35. package/src/jsx-runtime.ts +2 -0
  36. package/src/jsx.ts +786 -0
  37. package/src/lifecycle.ts +273 -0
  38. package/src/list-helpers.ts +619 -0
  39. package/src/memo.ts +14 -0
  40. package/src/node-ops.ts +185 -0
  41. package/src/props.ts +212 -0
  42. package/src/reconcile.ts +151 -0
  43. package/src/ref.ts +25 -0
  44. package/src/scheduler.ts +12 -0
  45. package/src/signal.ts +1278 -0
  46. package/src/slim.ts +68 -0
  47. package/src/store.ts +210 -0
  48. package/src/suspense.ts +187 -0
  49. package/src/transition.ts +128 -0
  50. package/src/types.ts +172 -0
  51. package/src/versioned-signal.ts +58 -0
package/src/types.ts ADDED
@@ -0,0 +1,172 @@
1
+ // ============================================================================
2
+ // DOM Types
3
+ // ============================================================================
4
+
5
+ /** Any DOM node that can be rendered */
6
+ export type DOMElement = Node
7
+
8
+ /** Cleanup function type */
9
+ export type Cleanup = () => void
10
+
11
+ // ============================================================================
12
+ // Virtual Node Types
13
+ // ============================================================================
14
+
15
+ /** Fict Virtual Node - represents a component or element in the virtual tree */
16
+ export interface FictVNode {
17
+ /** Element type: tag name, Fragment symbol, or component function */
18
+ type: string | symbol | ((props: Record<string, unknown>) => FictNode)
19
+ /** Props passed to the element/component */
20
+ props: Record<string, unknown> | null
21
+ /** Optional key for list rendering optimization */
22
+ key?: string | undefined
23
+ }
24
+
25
+ /**
26
+ * Fict Node - represents any renderable value
27
+ * This type covers all possible values that can appear in JSX
28
+ */
29
+ export type FictNode = FictVNode | FictNode[] | Node | string | number | boolean | null | undefined
30
+
31
+ // ============================================================================
32
+ // Reactive Types
33
+ // ============================================================================
34
+
35
+ /** A value that may be either static or reactive (wrapped in a getter function) */
36
+ export type MaybeReactive<T> = T | (() => T)
37
+
38
+ /** A reactive getter function */
39
+ export type Reactive<T> = () => T
40
+
41
+ // ============================================================================
42
+ // Component Types
43
+ // ============================================================================
44
+
45
+ /** Props that all components receive */
46
+ export interface BaseProps {
47
+ /** Optional key for list rendering */
48
+ key?: string | number
49
+ /** Optional children */
50
+ children?: FictNode | FictNode[]
51
+ }
52
+
53
+ /** A Fict component function */
54
+ export type Component<P extends Record<string, unknown> = Record<string, unknown>> = (
55
+ props: P & BaseProps,
56
+ ) => FictNode
57
+
58
+ /** Props with children */
59
+ export type PropsWithChildren<P = unknown> = P & {
60
+ children?: FictNode | FictNode[]
61
+ }
62
+
63
+ // ============================================================================
64
+ // Error Handling Types
65
+ // ============================================================================
66
+
67
+ export interface ErrorInfo {
68
+ source: 'render' | 'effect' | 'event' | 'renderChild' | 'cleanup'
69
+ componentName?: string
70
+ eventName?: string
71
+ }
72
+
73
+ // ============================================================================
74
+ // Event Handler Types
75
+ // ============================================================================
76
+
77
+ /** Event handler type for type-safe event handling */
78
+ export type EventHandler<E extends Event = Event> = (event: E) => void
79
+
80
+ /** Common event handlers */
81
+ export interface DOMEventHandlers {
82
+ onClick?: EventHandler<MouseEvent>
83
+ onDblClick?: EventHandler<MouseEvent>
84
+ onMouseDown?: EventHandler<MouseEvent>
85
+ onMouseUp?: EventHandler<MouseEvent>
86
+ onMouseMove?: EventHandler<MouseEvent>
87
+ onMouseEnter?: EventHandler<MouseEvent>
88
+ onMouseLeave?: EventHandler<MouseEvent>
89
+ onMouseOver?: EventHandler<MouseEvent>
90
+ onMouseOut?: EventHandler<MouseEvent>
91
+
92
+ onKeyDown?: EventHandler<KeyboardEvent>
93
+ onKeyUp?: EventHandler<KeyboardEvent>
94
+ onKeyPress?: EventHandler<KeyboardEvent>
95
+
96
+ onFocus?: EventHandler<FocusEvent>
97
+ onBlur?: EventHandler<FocusEvent>
98
+
99
+ onInput?: EventHandler<InputEvent>
100
+ onChange?: EventHandler<Event>
101
+ onSubmit?: EventHandler<SubmitEvent>
102
+
103
+ onScroll?: EventHandler<Event>
104
+ onWheel?: EventHandler<WheelEvent>
105
+
106
+ onDragStart?: EventHandler<DragEvent>
107
+ onDrag?: EventHandler<DragEvent>
108
+ onDragEnd?: EventHandler<DragEvent>
109
+ onDragEnter?: EventHandler<DragEvent>
110
+ onDragLeave?: EventHandler<DragEvent>
111
+ onDragOver?: EventHandler<DragEvent>
112
+ onDrop?: EventHandler<DragEvent>
113
+
114
+ onTouchStart?: EventHandler<TouchEvent>
115
+ onTouchMove?: EventHandler<TouchEvent>
116
+ onTouchEnd?: EventHandler<TouchEvent>
117
+ onTouchCancel?: EventHandler<TouchEvent>
118
+
119
+ onAnimationStart?: EventHandler<AnimationEvent>
120
+ onAnimationEnd?: EventHandler<AnimationEvent>
121
+ onAnimationIteration?: EventHandler<AnimationEvent>
122
+
123
+ onTransitionEnd?: EventHandler<TransitionEvent>
124
+ }
125
+
126
+ // ============================================================================
127
+ // Ref Types
128
+ // ============================================================================
129
+
130
+ /** Ref callback type */
131
+ export type RefCallback<T extends HTMLElement = HTMLElement> = (element: T) => void
132
+
133
+ /** Ref object type (for future use with createRef) */
134
+ export interface RefObject<T extends HTMLElement = HTMLElement> {
135
+ current: T | null
136
+ }
137
+
138
+ /** Ref type that can be either callback or object */
139
+ export type Ref<T extends HTMLElement = HTMLElement> = RefCallback<T> | RefObject<T>
140
+
141
+ // ============================================================================
142
+ // Style Types
143
+ // ============================================================================
144
+
145
+ /** CSS style value - can be string or number (number becomes px) */
146
+ export type StyleValue = string | number
147
+
148
+ /** CSS style object */
149
+ export type CSSStyleObject = {
150
+ [K in keyof CSSStyleDeclaration]?: StyleValue
151
+ } & Record<string, StyleValue>
152
+
153
+ /** Style prop type - can be string or object */
154
+ export type StyleProp = string | CSSStyleObject | null | undefined
155
+
156
+ // ============================================================================
157
+ // Class Types
158
+ // ============================================================================
159
+
160
+ /** Class object for conditional classes */
161
+ export type ClassObject = Record<string, boolean | undefined | null>
162
+
163
+ /** Class prop type - can be string or object */
164
+ export type ClassProp = string | ClassObject | null | undefined
165
+
166
+ // ============================================================================
167
+ // Suspense Types
168
+ // ============================================================================
169
+
170
+ export interface SuspenseToken {
171
+ then: Promise<unknown>['then']
172
+ }
@@ -0,0 +1,58 @@
1
+ import { createSignal } from './signal'
2
+
3
+ export interface VersionedSignalOptions<T> {
4
+ equals?: (prev: T, next: T) => boolean
5
+ }
6
+
7
+ export interface VersionedSignal<T> {
8
+ /** Reactive read that tracks both the value and version counter */
9
+ read: () => T
10
+ /** Write a new value, forcing a version bump when value is equal */
11
+ write: (next: T) => void
12
+ /** Force a version bump without changing the value */
13
+ force: () => void
14
+ /** Read the current version without creating a dependency */
15
+ peekVersion: () => number
16
+ /** Read the current value without tracking */
17
+ peekValue: () => T
18
+ }
19
+
20
+ /**
21
+ * Create a signal wrapper that forces subscribers to update when the same reference is written.
22
+ *
23
+ * Useful for compiler-generated keyed list items where updates may reuse the same object reference.
24
+ */
25
+ export function createVersionedSignal<T>(
26
+ initialValue: T,
27
+ options?: VersionedSignalOptions<T>,
28
+ ): VersionedSignal<T> {
29
+ const equals = options?.equals ?? Object.is
30
+ const value = createSignal(initialValue)
31
+ const version = createSignal(0)
32
+
33
+ const bumpVersion = () => {
34
+ const next = version() + 1
35
+ version(next)
36
+ }
37
+
38
+ return {
39
+ read: () => {
40
+ // Track both version and value to ensure equal writes notify subscribers
41
+ version()
42
+ return value()
43
+ },
44
+ write: (next: T) => {
45
+ const prev = value()
46
+ if (!equals(prev, next)) {
47
+ value(next)
48
+ return
49
+ }
50
+ bumpVersion()
51
+ },
52
+ force: () => {
53
+ bumpVersion()
54
+ },
55
+ peekVersion: () => version(),
56
+ peekValue: () => value(),
57
+ }
58
+ }