@pyreon/core 0.24.4 → 0.24.6

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 (56) hide show
  1. package/lib/analysis/index.js.html +1 -1
  2. package/lib/index.js +53 -31
  3. package/package.json +2 -6
  4. package/src/compat-marker.ts +0 -79
  5. package/src/compat-shared.ts +0 -80
  6. package/src/component.ts +0 -98
  7. package/src/context.ts +0 -349
  8. package/src/defer.ts +0 -279
  9. package/src/dynamic.ts +0 -32
  10. package/src/env.d.ts +0 -6
  11. package/src/error-boundary.ts +0 -90
  12. package/src/for.ts +0 -51
  13. package/src/h.ts +0 -80
  14. package/src/index.ts +0 -80
  15. package/src/jsx-dev-runtime.ts +0 -2
  16. package/src/jsx-runtime.ts +0 -747
  17. package/src/lazy.ts +0 -25
  18. package/src/lifecycle.ts +0 -152
  19. package/src/manifest.ts +0 -579
  20. package/src/map-array.ts +0 -42
  21. package/src/portal.ts +0 -39
  22. package/src/props.ts +0 -269
  23. package/src/ref.ts +0 -32
  24. package/src/show.ts +0 -121
  25. package/src/style.ts +0 -102
  26. package/src/suspense.ts +0 -52
  27. package/src/telemetry.ts +0 -120
  28. package/src/tests/compat-marker.test.ts +0 -96
  29. package/src/tests/compat-shared.test.ts +0 -99
  30. package/src/tests/component.test.ts +0 -281
  31. package/src/tests/context.test.ts +0 -629
  32. package/src/tests/core.test.ts +0 -1290
  33. package/src/tests/cx.test.ts +0 -70
  34. package/src/tests/defer.test.ts +0 -359
  35. package/src/tests/dynamic.test.ts +0 -87
  36. package/src/tests/error-boundary.test.ts +0 -181
  37. package/src/tests/extract-props-overloads.types.test.ts +0 -135
  38. package/src/tests/for.test.ts +0 -117
  39. package/src/tests/h.test.ts +0 -221
  40. package/src/tests/jsx-compat.test.tsx +0 -86
  41. package/src/tests/lazy.test.ts +0 -100
  42. package/src/tests/lifecycle.test.ts +0 -350
  43. package/src/tests/manifest-snapshot.test.ts +0 -100
  44. package/src/tests/map-array.test.ts +0 -313
  45. package/src/tests/native-marker-error-boundary.test.ts +0 -12
  46. package/src/tests/portal.test.ts +0 -48
  47. package/src/tests/props-extended.test.ts +0 -157
  48. package/src/tests/props.test.ts +0 -250
  49. package/src/tests/reactive-context.test.ts +0 -69
  50. package/src/tests/reactive-props.test.ts +0 -157
  51. package/src/tests/ref.test.ts +0 -70
  52. package/src/tests/show.test.ts +0 -314
  53. package/src/tests/style.test.ts +0 -157
  54. package/src/tests/suspense.test.ts +0 -139
  55. package/src/tests/telemetry.test.ts +0 -297
  56. package/src/types.ts +0 -116
package/src/lazy.ts DELETED
@@ -1,25 +0,0 @@
1
- import { signal } from '@pyreon/reactivity'
2
- import { h } from './h'
3
- import type { LazyComponent } from './suspense'
4
- import type { ComponentFn, Props } from './types'
5
-
6
- export function lazy<P extends Props>(
7
- load: () => Promise<{ default: ComponentFn<P> }>,
8
- ): LazyComponent<P> {
9
- const loaded = signal<ComponentFn<P> | null>(null)
10
- const error = signal<Error | null>(null)
11
-
12
- load()
13
- .then((m) => loaded.set(m.default))
14
- .catch((e) => error.set(e instanceof Error ? e : new Error(String(e))))
15
-
16
- const wrapper = ((props: P) => {
17
- const err = error()
18
- if (err) throw err
19
- const comp = loaded()
20
- return comp ? h(comp as ComponentFn, props as Props) : null
21
- }) as LazyComponent<P>
22
-
23
- wrapper.__loading = () => loaded() === null && error() === null
24
- return wrapper
25
- }
package/src/lifecycle.ts DELETED
@@ -1,152 +0,0 @@
1
- import type { CleanupFn, LifecycleHooks } from './types'
2
-
3
- // Dev-mode gate: see `pyreon/no-process-dev-gate` lint rule for why this
4
- // uses `import.meta.env.DEV` instead of `typeof process !== 'undefined'`.
5
- const __DEV__ = process.env.NODE_ENV !== 'production'
6
-
7
- // The currently-executing component's hook storage, set by the renderer
8
- // before calling the component function, cleared immediately after.
9
- let _current: LifecycleHooks | null = null
10
-
11
- export function setCurrentHooks(hooks: LifecycleHooks | null) {
12
- _current = hooks
13
- }
14
-
15
- export function getCurrentHooks(): LifecycleHooks | null {
16
- return _current
17
- }
18
-
19
- /**
20
- * Extract the first stack frame that's NOT inside the framework itself.
21
- * Walks the stack from top, skipping:
22
- * - V8/JSC internals (`at <anonymous>`, no filename)
23
- * - Framework files (packages/core/core/src/lifecycle.ts, etc.)
24
- * - The warning infra itself (warnOutsideSetup, the hook wrapper)
25
- *
26
- * Returns a string like "at MyComponent (src/components/Foo.tsx:42:15)"
27
- * — the call site a user needs to fix. Returns an empty string if no
28
- * user-code frame is found (unlikely in practice).
29
- */
30
- function captureCallSite(): string {
31
- const err = new Error()
32
- const stack = err.stack
33
- if (!stack) return ''
34
- const lines = stack.split('\n')
35
- // Framework paths to skip — conservative, matches the packages that
36
- // contain lifecycle / provide / context internals and call these hooks.
37
- // Framework / infra paths + function names to skip. Match BOTH source
38
- // form (`packages/X/src/...` — workspace consumers via the `bun`
39
- // condition) AND published-bundle form (`node_modules/@pyreon/X/lib/...`
40
- // — npm consumers). Pre-fix only the source paths were covered, so
41
- // every published-package consumer (i.e. almost everyone in production
42
- // dev) saw the warning's "Called from:" line point at the framework's
43
- // own bundle code, defeating the user-actionable hint. Function-name
44
- // patterns (`captureCallSite`, `warnOutsideSetup`) cover the case where
45
- // bundling rewrites the source path but the symbol name survives.
46
- const skipPatterns = [
47
- // ── Source form (workspace / `bun` condition) ──────────────────────
48
- /\/lifecycle\.[tj]s/,
49
- /\/context\.[tj]s/,
50
- /\/component\.[tj]s/,
51
- // ── Function-name match (works through bundling / minification when
52
- // symbol names survive) ─────────────────────────────────────────
53
- /\bcaptureCallSite\b/,
54
- /\bwarnOutsideSetup\b/,
55
- // ── Source-tree paths for every framework package that internally
56
- // calls lifecycle hooks (HeadProvider, RouterProvider, ThemeProvider,
57
- // PyreonUI, etc.). Without each, a published-package consumer with
58
- // `useHead()` or `provide()` would see the "Called from:" line
59
- // point at the LIBRARY's source, not their own component. ───────
60
- /\/(core|reactivity|runtime-dom|runtime-server|router|head|ui-core|styler|unistyle|rocketstyle|attrs|elements|kinetic)\/src\//,
61
- // ── Published-bundle form (npm consumers): bundles always at
62
- // `node_modules/@pyreon/<name>/lib/...`. The blanket
63
- // `@pyreon/[a-z-]+/lib/` catches every package without per-name
64
- // maintenance. ────────────────────────────────────────────────────
65
- /node_modules\/@pyreon\/[^/]+\/lib\//,
66
- /@pyreon\/[a-z-]+\/lib\//,
67
- // ── Runtime / engine internals ─────────────────────────────────────
68
- /node:internal/,
69
- /webpack-internal/,
70
- /<anonymous>/,
71
- ]
72
- for (const line of lines) {
73
- if (!line.includes('at ')) continue
74
- if (skipPatterns.some((p) => p.test(line))) continue
75
- // Strip leading " at " and return the rest
76
- return line.trim()
77
- }
78
- return ''
79
- }
80
-
81
- function warnOutsideSetup(hookName: string): void {
82
- if (__DEV__ && !_current) {
83
- const callSite = captureCallSite()
84
- // Local name must NOT shadow the `location` browser global (poor
85
- // hygiene + trips SSR static analysis into a false positive).
86
- const callSiteSuffix = callSite ? `\n Called from: ${callSite}` : ''
87
- // oxlint-disable-next-line no-console
88
- console.warn(
89
- `[Pyreon] ${hookName}() called outside component setup. ` +
90
- "Lifecycle hooks must be called synchronously during a component's setup function." +
91
- callSiteSuffix +
92
- (hookName === 'onUnmount'
93
- ? '\n Hint: `provide()` internally calls onUnmount(). If you use provide(), ensure it runs during synchronous component setup — not inside effects, callbacks, or after awaits.'
94
- : ''),
95
- )
96
- }
97
- }
98
-
99
- /**
100
- * Register a callback to run after the component is mounted to the DOM.
101
- * Optionally return a cleanup function — it will run on unmount.
102
- */
103
- export function onMount(fn: () => CleanupFn | void | undefined) {
104
- warnOutsideSetup('onMount')
105
- if (_current) {
106
- if (_current.mount === null) _current.mount = []
107
- _current.mount.push(fn)
108
- }
109
- }
110
-
111
- /**
112
- * Register a callback to run when the component is removed from the DOM.
113
- */
114
- export function onUnmount(fn: () => void) {
115
- warnOutsideSetup('onUnmount')
116
- if (_current) {
117
- if (_current.unmount === null) _current.unmount = []
118
- _current.unmount.push(fn)
119
- }
120
- }
121
-
122
- /**
123
- * Register a callback to run after each reactive update.
124
- */
125
- export function onUpdate(fn: () => void) {
126
- warnOutsideSetup('onUpdate')
127
- if (_current) {
128
- if (_current.update === null) _current.update = []
129
- _current.update.push(fn)
130
- }
131
- }
132
-
133
- /**
134
- * Register an error handler for this component subtree.
135
- *
136
- * When an error is thrown during rendering or in a child component,
137
- * the nearest `onErrorCaptured` handler is called with the error.
138
- * Return `true` to mark the error as handled and stop propagation.
139
- *
140
- * @example
141
- * onErrorCaptured((err) => {
142
- * setError(String(err))
143
- * return true // handled — don't propagate
144
- * })
145
- */
146
- export function onErrorCaptured(fn: (err: unknown) => boolean | undefined) {
147
- warnOutsideSetup('onErrorCaptured')
148
- if (_current) {
149
- if (_current.error === null) _current.error = []
150
- _current.error.push(fn)
151
- }
152
- }