@pyreon/core 0.11.5 → 0.11.7

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 (47) hide show
  1. package/README.md +2 -2
  2. package/lib/analysis/index.js.html +1 -1
  3. package/lib/index.js +33 -5
  4. package/lib/index.js.map +1 -1
  5. package/lib/jsx-dev-runtime.js.map +1 -1
  6. package/lib/jsx-runtime.js.map +1 -1
  7. package/lib/types/index.d.ts +145 -98
  8. package/lib/types/index.d.ts.map +1 -1
  9. package/lib/types/jsx-dev-runtime.d.ts +94 -94
  10. package/lib/types/jsx-runtime.d.ts +94 -94
  11. package/package.json +11 -11
  12. package/src/component.ts +2 -2
  13. package/src/context.ts +75 -4
  14. package/src/dynamic.ts +4 -4
  15. package/src/error-boundary.ts +10 -10
  16. package/src/for.ts +8 -2
  17. package/src/h.ts +4 -4
  18. package/src/index.ts +30 -27
  19. package/src/jsx-dev-runtime.ts +1 -1
  20. package/src/jsx-runtime.ts +108 -108
  21. package/src/lazy.ts +4 -4
  22. package/src/lifecycle.ts +6 -6
  23. package/src/portal.ts +2 -2
  24. package/src/show.ts +4 -4
  25. package/src/style.ts +51 -51
  26. package/src/suspense.ts +8 -8
  27. package/src/telemetry.ts +1 -1
  28. package/src/tests/component.test.ts +60 -60
  29. package/src/tests/context.test.ts +102 -102
  30. package/src/tests/core.test.ts +376 -376
  31. package/src/tests/cx.test.ts +34 -34
  32. package/src/tests/dynamic.test.ts +28 -28
  33. package/src/tests/error-boundary.test.ts +51 -51
  34. package/src/tests/for.test.ts +26 -26
  35. package/src/tests/h.test.ts +100 -100
  36. package/src/tests/jsx-compat.test.tsx +41 -41
  37. package/src/tests/lazy.test.ts +28 -28
  38. package/src/tests/lifecycle.test.ts +35 -35
  39. package/src/tests/map-array.test.ts +36 -36
  40. package/src/tests/portal.test.ts +21 -21
  41. package/src/tests/props-extended.test.ts +51 -51
  42. package/src/tests/props.test.ts +62 -62
  43. package/src/tests/ref.test.ts +20 -20
  44. package/src/tests/show.test.ts +94 -94
  45. package/src/tests/style.test.ts +101 -101
  46. package/src/tests/suspense.test.ts +44 -44
  47. package/src/tests/telemetry.test.ts +35 -35
@@ -1,4 +1,4 @@
1
- import { runWithHooks } from "../component"
1
+ import { runWithHooks } from '../component'
2
2
  import {
3
3
  createContext,
4
4
  popContext,
@@ -7,96 +7,96 @@ import {
7
7
  setContextStackProvider,
8
8
  useContext,
9
9
  withContext,
10
- } from "../context"
11
- import type { ComponentFn, Props } from "../types"
10
+ } from '../context'
11
+ import type { ComponentFn, Props } from '../types'
12
12
 
13
- describe("createContext", () => {
14
- test("returns context with unique symbol id", () => {
15
- const ctx = createContext("default")
16
- expect(typeof ctx.id).toBe("symbol")
17
- expect(ctx.defaultValue).toBe("default")
13
+ describe('createContext', () => {
14
+ test('returns context with unique symbol id', () => {
15
+ const ctx = createContext('default')
16
+ expect(typeof ctx.id).toBe('symbol')
17
+ expect(ctx.defaultValue).toBe('default')
18
18
  })
19
19
 
20
- test("each context has a unique id", () => {
20
+ test('each context has a unique id', () => {
21
21
  const a = createContext(1)
22
22
  const b = createContext(2)
23
23
  expect(a.id).not.toBe(b.id)
24
24
  })
25
25
 
26
- test("undefined default value", () => {
26
+ test('undefined default value', () => {
27
27
  const ctx = createContext<string | undefined>(undefined)
28
28
  expect(ctx.defaultValue).toBeUndefined()
29
29
  })
30
30
 
31
- test("null default value", () => {
31
+ test('null default value', () => {
32
32
  const ctx = createContext<null>(null)
33
33
  expect(ctx.defaultValue).toBeNull()
34
34
  })
35
35
 
36
- test("object default value", () => {
37
- const obj = { theme: "dark", lang: "en" }
36
+ test('object default value', () => {
37
+ const obj = { theme: 'dark', lang: 'en' }
38
38
  const ctx = createContext(obj)
39
39
  expect(ctx.defaultValue).toBe(obj)
40
40
  })
41
41
 
42
- test("function default value", () => {
42
+ test('function default value', () => {
43
43
  const fn = () => 42
44
44
  const ctx = createContext(fn)
45
45
  expect(ctx.defaultValue).toBe(fn)
46
46
  })
47
47
  })
48
48
 
49
- describe("useContext", () => {
50
- test("returns default when no provider exists", () => {
51
- const ctx = createContext("fallback")
52
- expect(useContext(ctx)).toBe("fallback")
49
+ describe('useContext', () => {
50
+ test('returns default when no provider exists', () => {
51
+ const ctx = createContext('fallback')
52
+ expect(useContext(ctx)).toBe('fallback')
53
53
  })
54
54
 
55
- test("returns provided value from pushContext", () => {
56
- const ctx = createContext("default")
57
- pushContext(new Map([[ctx.id, "provided"]]))
58
- expect(useContext(ctx)).toBe("provided")
55
+ test('returns provided value from pushContext', () => {
56
+ const ctx = createContext('default')
57
+ pushContext(new Map([[ctx.id, 'provided']]))
58
+ expect(useContext(ctx)).toBe('provided')
59
59
  popContext()
60
60
  })
61
61
 
62
- test("returns innermost value with nested pushContext", () => {
63
- const ctx = createContext("default")
64
- pushContext(new Map([[ctx.id, "outer"]]))
65
- pushContext(new Map([[ctx.id, "inner"]]))
66
- expect(useContext(ctx)).toBe("inner")
62
+ test('returns innermost value with nested pushContext', () => {
63
+ const ctx = createContext('default')
64
+ pushContext(new Map([[ctx.id, 'outer']]))
65
+ pushContext(new Map([[ctx.id, 'inner']]))
66
+ expect(useContext(ctx)).toBe('inner')
67
67
  popContext()
68
- expect(useContext(ctx)).toBe("outer")
68
+ expect(useContext(ctx)).toBe('outer')
69
69
  popContext()
70
70
  })
71
71
 
72
- test("different contexts in same frame are independent", () => {
73
- const ctxA = createContext("a-default")
74
- const ctxB = createContext("b-default")
72
+ test('different contexts in same frame are independent', () => {
73
+ const ctxA = createContext('a-default')
74
+ const ctxB = createContext('b-default')
75
75
  const frame = new Map<symbol, unknown>([
76
- [ctxA.id, "a-value"],
77
- [ctxB.id, "b-value"],
76
+ [ctxA.id, 'a-value'],
77
+ [ctxB.id, 'b-value'],
78
78
  ])
79
79
  pushContext(frame)
80
- expect(useContext(ctxA)).toBe("a-value")
81
- expect(useContext(ctxB)).toBe("b-value")
80
+ expect(useContext(ctxA)).toBe('a-value')
81
+ expect(useContext(ctxB)).toBe('b-value')
82
82
  popContext()
83
83
  })
84
84
 
85
- test("context not in frame falls through to previous frame", () => {
86
- const ctxA = createContext("a-default")
87
- const ctxB = createContext("b-default")
88
- pushContext(new Map([[ctxA.id, "a-outer"]]))
89
- pushContext(new Map([[ctxB.id, "b-inner"]]))
85
+ test('context not in frame falls through to previous frame', () => {
86
+ const ctxA = createContext('a-default')
87
+ const ctxB = createContext('b-default')
88
+ pushContext(new Map([[ctxA.id, 'a-outer']]))
89
+ pushContext(new Map([[ctxB.id, 'b-inner']]))
90
90
  // ctxA is not in the inner frame, should fall through to outer
91
- expect(useContext(ctxA)).toBe("a-outer")
92
- expect(useContext(ctxB)).toBe("b-inner")
91
+ expect(useContext(ctxA)).toBe('a-outer')
92
+ expect(useContext(ctxB)).toBe('b-inner')
93
93
  popContext()
94
94
  popContext()
95
95
  })
96
96
  })
97
97
 
98
- describe("pushContext / popContext", () => {
99
- test("push and pop maintain correct stack order", () => {
98
+ describe('pushContext / popContext', () => {
99
+ test('push and pop maintain correct stack order', () => {
100
100
  const ctx = createContext(0)
101
101
  pushContext(new Map([[ctx.id, 1]]))
102
102
  pushContext(new Map([[ctx.id, 2]]))
@@ -110,50 +110,50 @@ describe("pushContext / popContext", () => {
110
110
  expect(useContext(ctx)).toBe(0) // default
111
111
  })
112
112
 
113
- test("popContext on empty stack warns in dev mode", () => {
114
- const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {})
113
+ test('popContext on empty stack warns in dev mode', () => {
114
+ const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {})
115
115
  popContext()
116
116
  expect(warnSpy).toHaveBeenCalledWith(
117
- expect.stringContaining("popContext() called on an empty context stack"),
117
+ expect.stringContaining('popContext() called on an empty context stack'),
118
118
  )
119
119
  warnSpy.mockRestore()
120
120
  })
121
121
  })
122
122
 
123
- describe("withContext", () => {
124
- test("provides value during callback execution", () => {
125
- const ctx = createContext("default")
126
- let captured = ""
127
- withContext(ctx, "inside", () => {
123
+ describe('withContext', () => {
124
+ test('provides value during callback execution', () => {
125
+ const ctx = createContext('default')
126
+ let captured = ''
127
+ withContext(ctx, 'inside', () => {
128
128
  captured = useContext(ctx)
129
129
  })
130
- expect(captured).toBe("inside")
130
+ expect(captured).toBe('inside')
131
131
  // After withContext, should be back to default
132
- expect(useContext(ctx)).toBe("default")
132
+ expect(useContext(ctx)).toBe('default')
133
133
  })
134
134
 
135
- test("restores stack on normal completion", () => {
136
- const ctx = createContext("default")
137
- withContext(ctx, "temp", () => {
138
- expect(useContext(ctx)).toBe("temp")
135
+ test('restores stack on normal completion', () => {
136
+ const ctx = createContext('default')
137
+ withContext(ctx, 'temp', () => {
138
+ expect(useContext(ctx)).toBe('temp')
139
139
  })
140
- expect(useContext(ctx)).toBe("default")
140
+ expect(useContext(ctx)).toBe('default')
141
141
  })
142
142
 
143
- test("restores stack even when callback throws", () => {
144
- const ctx = createContext("safe")
143
+ test('restores stack even when callback throws', () => {
144
+ const ctx = createContext('safe')
145
145
  try {
146
- withContext(ctx, "dangerous", () => {
147
- expect(useContext(ctx)).toBe("dangerous")
148
- throw new Error("boom")
146
+ withContext(ctx, 'dangerous', () => {
147
+ expect(useContext(ctx)).toBe('dangerous')
148
+ throw new Error('boom')
149
149
  })
150
150
  } catch {
151
151
  // expected
152
152
  }
153
- expect(useContext(ctx)).toBe("safe")
153
+ expect(useContext(ctx)).toBe('safe')
154
154
  })
155
155
 
156
- test("nested withContext calls", () => {
156
+ test('nested withContext calls', () => {
157
157
  const ctx = createContext(0)
158
158
  withContext(ctx, 1, () => {
159
159
  expect(useContext(ctx)).toBe(1)
@@ -169,90 +169,90 @@ describe("withContext", () => {
169
169
  expect(useContext(ctx)).toBe(0)
170
170
  })
171
171
 
172
- test("multiple contexts in nested withContext", () => {
173
- const theme = createContext("light")
174
- const lang = createContext("en")
172
+ test('multiple contexts in nested withContext', () => {
173
+ const theme = createContext('light')
174
+ const lang = createContext('en')
175
175
 
176
- withContext(theme, "dark", () => {
177
- withContext(lang, "fr", () => {
178
- expect(useContext(theme)).toBe("dark")
179
- expect(useContext(lang)).toBe("fr")
176
+ withContext(theme, 'dark', () => {
177
+ withContext(lang, 'fr', () => {
178
+ expect(useContext(theme)).toBe('dark')
179
+ expect(useContext(lang)).toBe('fr')
180
180
  })
181
- expect(useContext(lang)).toBe("en")
181
+ expect(useContext(lang)).toBe('en')
182
182
  })
183
- expect(useContext(theme)).toBe("light")
183
+ expect(useContext(theme)).toBe('light')
184
184
  })
185
185
  })
186
186
 
187
- describe("provide", () => {
188
- test("pushes context and registers unmount cleanup", () => {
189
- const ctx = createContext("default")
187
+ describe('provide', () => {
188
+ test('pushes context and registers unmount cleanup', () => {
189
+ const ctx = createContext('default')
190
190
  const { hooks } = runWithHooks(
191
191
  (() => {
192
- provide(ctx, "provided-value")
193
- expect(useContext(ctx)).toBe("provided-value")
192
+ provide(ctx, 'provided-value')
193
+ expect(useContext(ctx)).toBe('provided-value')
194
194
  return null
195
195
  }) as ComponentFn,
196
196
  {} as Props,
197
197
  )
198
198
  // Context should still be available after runWithHooks
199
- expect(useContext(ctx)).toBe("provided-value")
199
+ expect(useContext(ctx)).toBe('provided-value')
200
200
  // unmount hooks should include the popContext cleanup
201
201
  expect(hooks.unmount.length).toBeGreaterThanOrEqual(1)
202
202
  // Running unmount cleans up
203
203
  for (const fn of hooks.unmount) fn()
204
- expect(useContext(ctx)).toBe("default")
204
+ expect(useContext(ctx)).toBe('default')
205
205
  })
206
206
 
207
- test("multiple provides in same component", () => {
208
- const ctxA = createContext("a")
209
- const ctxB = createContext("b")
207
+ test('multiple provides in same component', () => {
208
+ const ctxA = createContext('a')
209
+ const ctxB = createContext('b')
210
210
  const { hooks } = runWithHooks(
211
211
  (() => {
212
- provide(ctxA, "A-value")
213
- provide(ctxB, "B-value")
212
+ provide(ctxA, 'A-value')
213
+ provide(ctxB, 'B-value')
214
214
  return null
215
215
  }) as ComponentFn,
216
216
  {} as Props,
217
217
  )
218
- expect(useContext(ctxA)).toBe("A-value")
219
- expect(useContext(ctxB)).toBe("B-value")
218
+ expect(useContext(ctxA)).toBe('A-value')
219
+ expect(useContext(ctxB)).toBe('B-value')
220
220
  // Clean up
221
221
  for (const fn of hooks.unmount) fn()
222
- expect(useContext(ctxA)).toBe("a")
223
- expect(useContext(ctxB)).toBe("b")
222
+ expect(useContext(ctxA)).toBe('a')
223
+ expect(useContext(ctxB)).toBe('b')
224
224
  })
225
225
  })
226
226
 
227
- describe("setContextStackProvider", () => {
228
- test("overrides the stack provider", () => {
227
+ describe('setContextStackProvider', () => {
228
+ test('overrides the stack provider', () => {
229
229
  const customStack: Map<symbol, unknown>[] = []
230
- const ctx = createContext("default")
230
+ const ctx = createContext('default')
231
231
 
232
232
  setContextStackProvider(() => customStack)
233
233
 
234
- customStack.push(new Map([[ctx.id, "custom"]]))
235
- expect(useContext(ctx)).toBe("custom")
234
+ customStack.push(new Map([[ctx.id, 'custom']]))
235
+ expect(useContext(ctx)).toBe('custom')
236
236
  customStack.pop()
237
- expect(useContext(ctx)).toBe("default")
237
+ expect(useContext(ctx)).toBe('default')
238
238
 
239
239
  // Restore default provider
240
240
  const freshStack: Map<symbol, unknown>[] = []
241
241
  setContextStackProvider(() => freshStack)
242
242
  })
243
243
 
244
- test("different providers see different stacks", () => {
245
- const ctx = createContext("default")
244
+ test('different providers see different stacks', () => {
245
+ const ctx = createContext('default')
246
246
  const stack1: Map<symbol, unknown>[] = []
247
247
  const stack2: Map<symbol, unknown>[] = []
248
248
 
249
249
  setContextStackProvider(() => stack1)
250
- pushContext(new Map([[ctx.id, "stack1-value"]]))
251
- expect(useContext(ctx)).toBe("stack1-value")
250
+ pushContext(new Map([[ctx.id, 'stack1-value']]))
251
+ expect(useContext(ctx)).toBe('stack1-value')
252
252
 
253
253
  // Switch to stack2 — should not see stack1's value
254
254
  setContextStackProvider(() => stack2)
255
- expect(useContext(ctx)).toBe("default")
255
+ expect(useContext(ctx)).toBe('default')
256
256
 
257
257
  // Clean up
258
258
  setContextStackProvider(() => stack1)