kiru 1.1.2 → 1.2.1

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 (87) hide show
  1. package/dist/appHandle.d.ts.map +1 -1
  2. package/dist/appHandle.js +4 -5
  3. package/dist/appHandle.js.map +1 -1
  4. package/dist/components/derive.d.ts +4 -0
  5. package/dist/components/derive.d.ts.map +1 -1
  6. package/dist/components/derive.js +8 -4
  7. package/dist/components/derive.js.map +1 -1
  8. package/dist/components/errorBoundary.d.ts +4 -0
  9. package/dist/components/errorBoundary.d.ts.map +1 -1
  10. package/dist/components/errorBoundary.js +4 -0
  11. package/dist/components/errorBoundary.js.map +1 -1
  12. package/dist/{signals/jsx.d.ts → components/for.d.ts} +7 -9
  13. package/dist/components/for.d.ts.map +1 -0
  14. package/dist/components/for.js +13 -0
  15. package/dist/components/for.js.map +1 -0
  16. package/dist/components/index.d.ts +2 -0
  17. package/dist/components/index.d.ts.map +1 -1
  18. package/dist/components/index.js +2 -0
  19. package/dist/components/index.js.map +1 -1
  20. package/dist/components/lazy.d.ts +4 -0
  21. package/dist/components/lazy.d.ts.map +1 -1
  22. package/dist/components/lazy.js +4 -0
  23. package/dist/components/lazy.js.map +1 -1
  24. package/dist/components/portal.d.ts +4 -0
  25. package/dist/components/portal.d.ts.map +1 -1
  26. package/dist/components/portal.js +4 -0
  27. package/dist/components/portal.js.map +1 -1
  28. package/dist/components/show.d.ts +18 -0
  29. package/dist/components/show.d.ts.map +1 -0
  30. package/dist/components/show.js +18 -0
  31. package/dist/components/show.js.map +1 -0
  32. package/dist/components/transition.d.ts +4 -0
  33. package/dist/components/transition.d.ts.map +1 -1
  34. package/dist/components/transition.js +4 -0
  35. package/dist/components/transition.js.map +1 -1
  36. package/dist/dom/nodes.d.ts.map +1 -1
  37. package/dist/dom/nodes.js +5 -1
  38. package/dist/dom/nodes.js.map +1 -1
  39. package/dist/dom/props.d.ts.map +1 -1
  40. package/dist/dom/props.js +23 -4
  41. package/dist/dom/props.js.map +1 -1
  42. package/dist/hooks/setup.d.ts +1 -1
  43. package/dist/hooks/setup.d.ts.map +1 -1
  44. package/dist/hooks/setup.js +111 -7
  45. package/dist/hooks/setup.js.map +1 -1
  46. package/dist/scheduler.d.ts.map +1 -1
  47. package/dist/scheduler.js +2 -3
  48. package/dist/scheduler.js.map +1 -1
  49. package/dist/signals/base.d.ts.map +1 -1
  50. package/dist/signals/base.js +23 -4
  51. package/dist/signals/base.js.map +1 -1
  52. package/dist/signals/computed.d.ts +1 -1
  53. package/dist/signals/computed.d.ts.map +1 -1
  54. package/dist/signals/computed.js +29 -21
  55. package/dist/signals/computed.js.map +1 -1
  56. package/dist/signals/index.d.ts +0 -6
  57. package/dist/signals/index.d.ts.map +1 -1
  58. package/dist/signals/index.js +0 -6
  59. package/dist/signals/index.js.map +1 -1
  60. package/dist/types.utils.d.ts +2 -0
  61. package/dist/types.utils.d.ts.map +1 -1
  62. package/dist/utils/vdom.d.ts +2 -1
  63. package/dist/utils/vdom.d.ts.map +1 -1
  64. package/dist/utils/vdom.js +4 -1
  65. package/dist/utils/vdom.js.map +1 -1
  66. package/package.json +1 -1
  67. package/src/appHandle.ts +6 -7
  68. package/src/components/derive.ts +9 -5
  69. package/src/components/errorBoundary.ts +4 -0
  70. package/src/{signals/jsx.ts → components/for.ts} +6 -12
  71. package/src/components/index.ts +2 -0
  72. package/src/components/lazy.ts +4 -0
  73. package/src/components/portal.ts +4 -0
  74. package/src/components/show.ts +32 -0
  75. package/src/components/transition.ts +4 -0
  76. package/src/dom/nodes.ts +5 -2
  77. package/src/dom/props.ts +28 -3
  78. package/src/hooks/setup.ts +144 -10
  79. package/src/scheduler.ts +2 -3
  80. package/src/signals/base.ts +21 -5
  81. package/src/signals/computed.ts +13 -4
  82. package/src/signals/index.ts +0 -7
  83. package/src/types.utils.ts +3 -0
  84. package/src/utils/vdom.ts +5 -0
  85. package/dist/signals/jsx.d.ts.map +0 -1
  86. package/dist/signals/jsx.js +0 -11
  87. package/dist/signals/jsx.js.map +0 -1
@@ -5,7 +5,7 @@ import {
5
5
  generateRandomID,
6
6
  registerVNodeCleanup,
7
7
  } from "../utils/index.js"
8
- import { $HMR_ACCEPT, $SIGNAL } from "../constants.js"
8
+ import { $DEV_FILE_LINK, $HMR_ACCEPT, $SIGNAL } from "../constants.js"
9
9
  import { __DEV__, isBrowser } from "../env.js"
10
10
  import { node } from "../globals.js"
11
11
  import { requestUpdate } from "../scheduler.js"
@@ -120,9 +120,19 @@ export class Signal<T> {
120
120
 
121
121
  subscribe(cb: (state: T, prevState?: T) => void): () => void {
122
122
  if (__DEV__) {
123
- const subs = signalSubsMap.get(this.$id)!
124
- subs!.add(cb)
125
- return () => signalSubsMap.get(this.$id)?.delete(cb)
123
+ const tgt = latest(this)
124
+ const subs = signalSubsMap.get(tgt.$id)!
125
+ if (__DEV__ && !subs) {
126
+ const name = tgt.displayName ?? tgt.$id
127
+ let message = `Attempting to subscribe to a signal that has been disposed: ${name}`
128
+ if ($DEV_FILE_LINK in tgt) {
129
+ message += `\nFile: ${tgt[$DEV_FILE_LINK]}`
130
+ }
131
+ message += `\nInitial value: ${tgt.$initialValue}`
132
+ throw new Error(message)
133
+ }
134
+ subs.add(cb)
135
+ return () => subs.delete(cb)
126
136
  }
127
137
  this.$subs!.add(cb)
128
138
  return () => this.$subs!.delete(cb)
@@ -130,7 +140,8 @@ export class Signal<T> {
130
140
 
131
141
  notify(filter?: (sub: SignalSubscriber) => boolean) {
132
142
  if (__DEV__) {
133
- return signalSubsMap.get(this.$id)?.forEach((sub) => {
143
+ const tgt = latest(this)
144
+ return signalSubsMap.get(tgt.$id)?.forEach((sub) => {
134
145
  if (filter && !filter(sub)) return
135
146
  const { $value, $prevValue } = latest(this)
136
147
  return sub($value, $prevValue)
@@ -148,12 +159,14 @@ export class Signal<T> {
148
159
 
149
160
  static subscribers(signal: Signal<any>) {
150
161
  if (__DEV__) {
162
+ signal = latest(signal)
151
163
  return signalSubsMap.get(signal.$id)!
152
164
  }
153
165
  return signal.$subs
154
166
  }
155
167
 
156
168
  static makeReadonly<T>(signal: Signal<T>): ReadonlySignal<T> {
169
+ if (__DEV__) signal = latest(signal)
157
170
  const desc = Object.getOwnPropertyDescriptor(signal, "value")
158
171
  if (desc && !desc.writable) return signal
159
172
  return Object.defineProperty(signal, "value", {
@@ -166,6 +179,7 @@ export class Signal<T> {
166
179
  }
167
180
 
168
181
  static makeWritable<T>(signal: Signal<T>): Signal<T> {
182
+ if (__DEV__) signal = latest(signal)
169
183
  const desc = Object.getOwnPropertyDescriptor(signal, "value")
170
184
  if (desc && desc.writable) return signal
171
185
  return Object.defineProperty(signal, "value", {
@@ -183,6 +197,7 @@ export class Signal<T> {
183
197
 
184
198
  static entangle<T>(signal: Signal<T>) {
185
199
  if (tracking.enabled === false) return
200
+ if (__DEV__) signal = latest(signal)
186
201
 
187
202
  const vNode = node.current
188
203
  const trackedSignalObservations = tracking.current()
@@ -200,6 +215,7 @@ export class Signal<T> {
200
215
  static dispose(signal: Signal<any>) {
201
216
  signal.$isDisposed = true
202
217
  if (__DEV__) {
218
+ signal = latest(signal)
203
219
  signalSubsMap.delete(signal.$id)
204
220
  if (isBrowser) window.__kiru.devtools?.untrack(signal)
205
221
  return
@@ -25,8 +25,16 @@ export class ComputedSignal<T> extends Signal<T> {
25
25
  },
26
26
  inject: (prev) => {
27
27
  inject(prev)
28
+ // Stop any pending reactions on the previous instance and mark
29
+ // this computed as dirty so it will recompute with the latest
30
+ // dependencies after HMR.
28
31
  ComputedSignal.stop(prev)
29
- this.$isDirty = prev.$isDirty
32
+ this.$isDirty = true
33
+ // Force a recompute immediately so any active subscribers (like
34
+ // text nodes bound to a computed signal) see the updated value
35
+ // after a hot reload where only its dependencies changed.
36
+ ComputedSignal.run(this)
37
+ this.notify()
30
38
  },
31
39
  destroy: () => {},
32
40
  } satisfies HMRAccept<ComputedSignal<T>>
@@ -38,6 +46,10 @@ export class ComputedSignal<T> extends Signal<T> {
38
46
  return super.value
39
47
  }
40
48
 
49
+ set value(next: T) {
50
+ super.value = next
51
+ }
52
+
41
53
  toString() {
42
54
  this.ensureNotDirty()
43
55
  return super.toString()
@@ -48,9 +60,6 @@ export class ComputedSignal<T> extends Signal<T> {
48
60
  return super.peek()
49
61
  }
50
62
 
51
- // @ts-expect-error
52
- set value(next: T) {}
53
-
54
63
  subscribe(cb: (state: T, prevState?: T) => void): () => void {
55
64
  if (this.$isDirty) {
56
65
  ComputedSignal.run(this)
@@ -1,12 +1,5 @@
1
- /**
2
- * ISSUES:
3
- * 1. signal subscription when mixing local and global signals get reversed in hmr for ONLY the first update after HMR is dom
4
- * 2. global computed will lose its vNode subscription on HMR
5
- * */
6
-
7
1
  export { Signal, signal } from "./base.js"
8
2
  export { ComputedSignal, computed } from "./computed.js"
9
3
  export { Effect, effect } from "./effect.js"
10
4
  export { unwrap, tick } from "./utils.js"
11
- export * from "./jsx.js"
12
5
  export * from "./types.js"
@@ -74,3 +74,6 @@ export type RecordHas<T extends Record<string, any>, U> = [
74
74
  ] extends [never]
75
75
  ? false
76
76
  : true
77
+
78
+ export type Falsy = false | 0 | 0n | "" | null | undefined
79
+ export type Truthy<T> = Exclude<T, Falsy>
package/src/utils/vdom.ts CHANGED
@@ -34,6 +34,7 @@ export {
34
34
  createVNodeId,
35
35
  registerVNodeCleanup,
36
36
  propsChanged,
37
+ depthSort,
37
38
  }
38
39
 
39
40
  function cloneElement(vNode: Kiru.VNode): Kiru.Element {
@@ -219,3 +220,7 @@ function propsChanged(
219
220
  }
220
221
  return false
221
222
  }
223
+
224
+ function depthSort(a: Kiru.VNode, b: Kiru.VNode): number {
225
+ return a.depth - b.depth
226
+ }
@@ -1 +0,0 @@
1
- {"version":3,"file":"jsx.d.ts","sourceRoot":"","sources":["../../src/signals/jsx.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAGvC,KAAK,wBAAwB,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,SAAS,OAAO,EAAE,IACxE,CAAC,SAAS,MAAM,CAAC,MAAM,CAAC,CAAC,GACrB,CAAC,SAAS,KAAK,CAAC,MAAM,CAAC,CAAC,GACtB,CAAC,GACD,KAAK,GACP,CAAC,SAAS,OAAO,EAAE,GACjB,CAAC,CAAC,MAAM,CAAC,GACT,KAAK,CAAA;AAEb,KAAK,QAAQ,CACX,CAAC,SAAS,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,SAAS,OAAO,EAAE,EAC5C,CAAC,GAAG,wBAAwB,CAAC,CAAC,CAAC,IAC7B;IACF,IAAI,EAAE,CAAC,CAAA;IACP,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;IACtB,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,KAAK,GAAG,CAAC,OAAO,CAAA;CAC/D,CAAA;AAED,wBAAgB,GAAG,CAAC,CAAC,SAAS,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,OAAO,EAAE,EAAE,EACvD,IAAI,EACJ,QAAQ,EACR,QAAQ,GACT,EAAE,QAAQ,CAAC,CAAC,CAAC,eAIb;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAA;IACrB,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,CAAA;IACzB,QAAQ,CAAC,EAAE,GAAG,CAAC,OAAO,CAAA;CACvB;AACD,wBAAgB,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,OAAO,CAEzE"}
@@ -1,11 +0,0 @@
1
- import { unwrap } from "./utils.js";
2
- export function For({ each, fallback, children, }) {
3
- const items = unwrap(each, true);
4
- if (items.length === 0)
5
- return fallback;
6
- return items.map(children);
7
- }
8
- export function Show({ children, when, fallback }) {
9
- return !!unwrap(when, true) ? children : fallback;
10
- }
11
- //# sourceMappingURL=jsx.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"jsx.js","sourceRoot":"","sources":["../../src/signals/jsx.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAoBnC,MAAM,UAAU,GAAG,CAAsC,EACvD,IAAI,EACJ,QAAQ,EACR,QAAQ,GACI;IACZ,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAA;IAChC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAA;IACvC,OAAO,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;AAC5B,CAAC;AAOD,MAAM,UAAU,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAa;IAC1D,OAAO,CAAC,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAA;AACnD,CAAC"}