@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.
- package/lib/analysis/index.js.html +1 -1
- package/lib/index.js +53 -31
- package/package.json +2 -6
- package/src/compat-marker.ts +0 -79
- package/src/compat-shared.ts +0 -80
- package/src/component.ts +0 -98
- package/src/context.ts +0 -349
- package/src/defer.ts +0 -279
- package/src/dynamic.ts +0 -32
- package/src/env.d.ts +0 -6
- package/src/error-boundary.ts +0 -90
- package/src/for.ts +0 -51
- package/src/h.ts +0 -80
- package/src/index.ts +0 -80
- package/src/jsx-dev-runtime.ts +0 -2
- package/src/jsx-runtime.ts +0 -747
- package/src/lazy.ts +0 -25
- package/src/lifecycle.ts +0 -152
- package/src/manifest.ts +0 -579
- package/src/map-array.ts +0 -42
- package/src/portal.ts +0 -39
- package/src/props.ts +0 -269
- package/src/ref.ts +0 -32
- package/src/show.ts +0 -121
- package/src/style.ts +0 -102
- package/src/suspense.ts +0 -52
- package/src/telemetry.ts +0 -120
- package/src/tests/compat-marker.test.ts +0 -96
- package/src/tests/compat-shared.test.ts +0 -99
- package/src/tests/component.test.ts +0 -281
- package/src/tests/context.test.ts +0 -629
- package/src/tests/core.test.ts +0 -1290
- package/src/tests/cx.test.ts +0 -70
- package/src/tests/defer.test.ts +0 -359
- package/src/tests/dynamic.test.ts +0 -87
- package/src/tests/error-boundary.test.ts +0 -181
- package/src/tests/extract-props-overloads.types.test.ts +0 -135
- package/src/tests/for.test.ts +0 -117
- package/src/tests/h.test.ts +0 -221
- package/src/tests/jsx-compat.test.tsx +0 -86
- package/src/tests/lazy.test.ts +0 -100
- package/src/tests/lifecycle.test.ts +0 -350
- package/src/tests/manifest-snapshot.test.ts +0 -100
- package/src/tests/map-array.test.ts +0 -313
- package/src/tests/native-marker-error-boundary.test.ts +0 -12
- package/src/tests/portal.test.ts +0 -48
- package/src/tests/props-extended.test.ts +0 -157
- package/src/tests/props.test.ts +0 -250
- package/src/tests/reactive-context.test.ts +0 -69
- package/src/tests/reactive-props.test.ts +0 -157
- package/src/tests/ref.test.ts +0 -70
- package/src/tests/show.test.ts +0 -314
- package/src/tests/style.test.ts +0 -157
- package/src/tests/suspense.test.ts +0 -139
- package/src/tests/telemetry.test.ts +0 -297
- 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
|
-
}
|