@pyreon/preact-compat 0.18.0 → 0.20.0

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.
@@ -5386,7 +5386,7 @@ var drawChart = (function (exports) {
5386
5386
  </script>
5387
5387
  <script>
5388
5388
  /*<!--*/
5389
- const data = {"version":2,"tree":{"name":"root","children":[{"name":"hooks.js","children":[{"name":"src","children":[{"uid":"3bf7c0f6-1","name":"jsx-runtime.ts"},{"uid":"3bf7c0f6-3","name":"hooks.ts"}]}]}],"isRoot":true},"nodeParts":{"3bf7c0f6-1":{"renderedLength":186,"gzipLength":138,"brotliLength":0,"metaUid":"3bf7c0f6-0"},"3bf7c0f6-3":{"renderedLength":7168,"gzipLength":2046,"brotliLength":0,"metaUid":"3bf7c0f6-2"}},"nodeMetas":{"3bf7c0f6-0":{"id":"/src/jsx-runtime.ts","moduleParts":{"hooks.js":"3bf7c0f6-1"},"imported":[{"uid":"3bf7c0f6-4"},{"uid":"3bf7c0f6-5"}],"importedBy":[{"uid":"3bf7c0f6-2"}]},"3bf7c0f6-2":{"id":"/src/hooks.ts","moduleParts":{"hooks.js":"3bf7c0f6-3"},"imported":[{"uid":"3bf7c0f6-4"},{"uid":"3bf7c0f6-0"}],"importedBy":[],"isEntry":true},"3bf7c0f6-4":{"id":"@pyreon/core","moduleParts":{},"imported":[],"importedBy":[{"uid":"3bf7c0f6-2"},{"uid":"3bf7c0f6-0"}]},"3bf7c0f6-5":{"id":"@pyreon/reactivity","moduleParts":{},"imported":[],"importedBy":[{"uid":"3bf7c0f6-0"}]}},"env":{"rollup":"4.23.0"},"options":{"gzip":true,"brotli":false,"sourcemap":false}};
5389
+ const data = {"version":2,"tree":{"name":"root","children":[{"name":"hooks.js","children":[{"name":"src","children":[{"uid":"55308b2d-1","name":"jsx-runtime.ts"},{"uid":"55308b2d-3","name":"hooks.ts"}]}]}],"isRoot":true},"nodeParts":{"55308b2d-1":{"renderedLength":186,"gzipLength":138,"brotliLength":0,"metaUid":"55308b2d-0"},"55308b2d-3":{"renderedLength":6949,"gzipLength":1987,"brotliLength":0,"metaUid":"55308b2d-2"}},"nodeMetas":{"55308b2d-0":{"id":"/src/jsx-runtime.ts","moduleParts":{"hooks.js":"55308b2d-1"},"imported":[{"uid":"55308b2d-4"},{"uid":"55308b2d-5"}],"importedBy":[{"uid":"55308b2d-2"}]},"55308b2d-2":{"id":"/src/hooks.ts","moduleParts":{"hooks.js":"55308b2d-3"},"imported":[{"uid":"55308b2d-4"},{"uid":"55308b2d-0"}],"importedBy":[],"isEntry":true},"55308b2d-4":{"id":"@pyreon/core","moduleParts":{},"imported":[],"importedBy":[{"uid":"55308b2d-2"},{"uid":"55308b2d-0"}]},"55308b2d-5":{"id":"@pyreon/reactivity","moduleParts":{},"imported":[],"importedBy":[{"uid":"55308b2d-0"}]}},"env":{"rollup":"4.23.0"},"options":{"gzip":true,"brotli":false,"sourcemap":false}};
5390
5390
 
5391
5391
  const run = () => {
5392
5392
  const width = window.innerWidth;
@@ -5386,7 +5386,7 @@ var drawChart = (function (exports) {
5386
5386
  </script>
5387
5387
  <script>
5388
5388
  /*<!--*/
5389
- const data = {"version":2,"tree":{"name":"root","children":[{"name":"jsx-runtime.js","children":[{"name":"src","children":[{"uid":"86b5580e-1","name":"jsx-runtime.ts"},{"uid":"86b5580e-3","name":"jsx-dev-runtime.ts"}]}]}],"isRoot":true},"nodeParts":{"86b5580e-1":{"renderedLength":5335,"gzipLength":1477,"brotliLength":0,"metaUid":"86b5580e-0"},"86b5580e-3":{"renderedLength":0,"gzipLength":0,"brotliLength":0,"metaUid":"86b5580e-2"}},"nodeMetas":{"86b5580e-0":{"id":"/src/jsx-runtime.ts","moduleParts":{"jsx-runtime.js":"86b5580e-1"},"imported":[{"uid":"86b5580e-4"},{"uid":"86b5580e-5"}],"importedBy":[{"uid":"86b5580e-2"}]},"86b5580e-2":{"id":"/src/jsx-dev-runtime.ts","moduleParts":{"jsx-runtime.js":"86b5580e-3"},"imported":[{"uid":"86b5580e-0"}],"importedBy":[],"isEntry":true},"86b5580e-4":{"id":"@pyreon/core","moduleParts":{},"imported":[],"importedBy":[{"uid":"86b5580e-0"}]},"86b5580e-5":{"id":"@pyreon/reactivity","moduleParts":{},"imported":[],"importedBy":[{"uid":"86b5580e-0"}]}},"env":{"rollup":"4.23.0"},"options":{"gzip":true,"brotli":false,"sourcemap":false}};
5389
+ const data = {"version":2,"tree":{"name":"root","children":[{"name":"jsx-runtime.js","children":[{"name":"src","children":[{"uid":"b3ca1a27-1","name":"jsx-runtime.ts"},{"uid":"b3ca1a27-3","name":"jsx-dev-runtime.ts"}]}]}],"isRoot":true},"nodeParts":{"b3ca1a27-1":{"renderedLength":4264,"gzipLength":1270,"brotliLength":0,"metaUid":"b3ca1a27-0"},"b3ca1a27-3":{"renderedLength":0,"gzipLength":0,"brotliLength":0,"metaUid":"b3ca1a27-2"}},"nodeMetas":{"b3ca1a27-0":{"id":"/src/jsx-runtime.ts","moduleParts":{"jsx-runtime.js":"b3ca1a27-1"},"imported":[{"uid":"b3ca1a27-4"},{"uid":"b3ca1a27-5"}],"importedBy":[{"uid":"b3ca1a27-2"}]},"b3ca1a27-2":{"id":"/src/jsx-dev-runtime.ts","moduleParts":{"jsx-runtime.js":"b3ca1a27-3"},"imported":[{"uid":"b3ca1a27-0"}],"importedBy":[],"isEntry":true},"b3ca1a27-4":{"id":"@pyreon/core","moduleParts":{},"imported":[],"importedBy":[{"uid":"b3ca1a27-0"}]},"b3ca1a27-5":{"id":"@pyreon/reactivity","moduleParts":{},"imported":[],"importedBy":[{"uid":"b3ca1a27-0"}]}},"env":{"rollup":"4.23.0"},"options":{"gzip":true,"brotli":false,"sourcemap":false}};
5390
5390
 
5391
5391
  const run = () => {
5392
5392
  const width = window.innerWidth;
package/lib/hooks.js CHANGED
@@ -1,4 +1,4 @@
1
- import { onErrorCaptured, useContext } from "@pyreon/core";
1
+ import { onErrorCaptured, shallowEqualProps, useContext } from "@pyreon/core";
2
2
 
3
3
  //#region src/jsx-runtime.ts
4
4
  let _currentCtx = null;
@@ -23,13 +23,6 @@ function depsChanged(a, b) {
23
23
  for (let i = 0; i < a.length; i++) if (!Object.is(a[i], b[i])) return true;
24
24
  return false;
25
25
  }
26
- function shallowEqual(a, b) {
27
- const keysA = Object.keys(a);
28
- const keysB = Object.keys(b);
29
- if (keysA.length !== keysB.length) return false;
30
- for (const k of keysA) if (!Object.is(a[k], b[k])) return false;
31
- return true;
32
- }
33
26
  /**
34
27
  * Preact-compatible `useState` — returns `[value, setter]`.
35
28
  * Triggers a component re-render when the setter is called.
@@ -190,7 +183,7 @@ function useId() {
190
183
  * so two `<MemoComp />` usages don't share memoization state.
191
184
  */
192
185
  function memo(component, areEqual) {
193
- const compare = areEqual ?? shallowEqual;
186
+ const compare = areEqual ?? shallowEqualProps;
194
187
  let _fallbackPrevProps = null;
195
188
  let _fallbackPrevResult = null;
196
189
  const memoized = (props) => {
@@ -1,4 +1,4 @@
1
- import { Fragment, h, isNativeCompat, onUnmount } from "@pyreon/core";
1
+ import { Fragment, h, isNativeCompat, mapCompatDomProps, onUnmount } from "@pyreon/core";
2
2
  import { signal } from "@pyreon/reactivity";
3
3
 
4
4
  //#region src/jsx-runtime.ts
@@ -141,35 +141,7 @@ function jsx(type, props, key) {
141
141
  return h(wrapCompatComponent(type), componentProps);
142
142
  }
143
143
  const childArray = children === void 0 ? [] : Array.isArray(children) ? children : [children];
144
- if (typeof type === "string") {
145
- if (propsWithKey.className !== void 0) {
146
- propsWithKey.class = propsWithKey.className;
147
- delete propsWithKey.className;
148
- }
149
- if (propsWithKey.htmlFor !== void 0) {
150
- propsWithKey.for = propsWithKey.htmlFor;
151
- delete propsWithKey.htmlFor;
152
- }
153
- if ((type === "input" || type === "textarea" || type === "select") && propsWithKey.onChange !== void 0) {
154
- if (propsWithKey.onInput === void 0) propsWithKey.onInput = propsWithKey.onChange;
155
- delete propsWithKey.onChange;
156
- }
157
- if (propsWithKey.autoFocus !== void 0) {
158
- propsWithKey.autofocus = propsWithKey.autoFocus;
159
- delete propsWithKey.autoFocus;
160
- }
161
- if (type === "input" || type === "textarea") {
162
- if (propsWithKey.defaultValue !== void 0 && propsWithKey.value === void 0) {
163
- propsWithKey.value = propsWithKey.defaultValue;
164
- delete propsWithKey.defaultValue;
165
- }
166
- if (propsWithKey.defaultChecked !== void 0 && propsWithKey.checked === void 0) {
167
- propsWithKey.checked = propsWithKey.defaultChecked;
168
- delete propsWithKey.defaultChecked;
169
- }
170
- }
171
- delete propsWithKey.suppressHydrationWarning;
172
- }
144
+ mapCompatDomProps(propsWithKey, type);
173
145
  return h(type, propsWithKey, ...childArray);
174
146
  }
175
147
  const jsxs = jsx;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pyreon/preact-compat",
3
- "version": "0.18.0",
3
+ "version": "0.20.0",
4
4
  "description": "Preact-compatible API shim for Pyreon — write Preact-style code that runs on Pyreon's reactive engine",
5
5
  "homepage": "https://github.com/pyreon/pyreon/tree/main/packages/preact-compat#readme",
6
6
  "bugs": {
@@ -64,13 +64,13 @@
64
64
  "prepublishOnly": "bun run build"
65
65
  },
66
66
  "dependencies": {
67
- "@pyreon/core": "^0.18.0",
68
- "@pyreon/reactivity": "^0.18.0",
69
- "@pyreon/runtime-dom": "^0.18.0"
67
+ "@pyreon/core": "^0.20.0",
68
+ "@pyreon/reactivity": "^0.20.0",
69
+ "@pyreon/runtime-dom": "^0.20.0"
70
70
  },
71
71
  "devDependencies": {
72
72
  "@happy-dom/global-registrator": "^20.8.9",
73
- "@pyreon/test-utils": "^0.13.5",
73
+ "@pyreon/test-utils": "^0.13.7",
74
74
  "@vitest/browser-playwright": "^4.1.4",
75
75
  "happy-dom": "^20.8.3"
76
76
  }
package/src/hooks.ts CHANGED
@@ -9,7 +9,7 @@
9
9
  */
10
10
 
11
11
  import type { VNodeChild } from '@pyreon/core'
12
- import { onErrorCaptured, useContext } from '@pyreon/core'
12
+ import { onErrorCaptured, shallowEqualProps as shallowEqual, useContext } from '@pyreon/core'
13
13
  import type { EffectEntry } from './jsx-runtime'
14
14
  import { getCurrentCtx, getHookIndex } from './jsx-runtime'
15
15
 
@@ -32,15 +32,7 @@ function depsChanged(a: unknown[] | undefined, b: unknown[] | undefined): boolea
32
32
  return false
33
33
  }
34
34
 
35
- function shallowEqual<P extends Record<string, unknown>>(a: P, b: P): boolean {
36
- const keysA = Object.keys(a)
37
- const keysB = Object.keys(b)
38
- if (keysA.length !== keysB.length) return false
39
- for (const k of keysA) {
40
- if (!Object.is(a[k], b[k])) return false
41
- }
42
- return true
43
- }
35
+ // `shallowEqual` lives in @pyreon/core (shared with @pyreon/react-compat).
44
36
 
45
37
  // ─── useState ────────────────────────────────────────────────────────────────
46
38
 
@@ -10,7 +10,7 @@
10
10
  */
11
11
 
12
12
  import type { ComponentFn, Props, VNode, VNodeChild } from '@pyreon/core'
13
- import { Fragment, h, isNativeCompat, onUnmount } from '@pyreon/core'
13
+ import { Fragment, h, isNativeCompat, mapCompatDomProps, onUnmount } from '@pyreon/core'
14
14
  import { signal } from '@pyreon/reactivity'
15
15
  import type { Component } from './index'
16
16
 
@@ -251,49 +251,9 @@ export function jsx(
251
251
  // DOM element or symbol (Fragment): children go in vnode.children
252
252
  const childArray = children === undefined ? [] : Array.isArray(children) ? children : [children]
253
253
 
254
- // Map Preact-style attributes to standard HTML attributes
255
- if (typeof type === 'string') {
256
- if (propsWithKey.className !== undefined) {
257
- propsWithKey.class = propsWithKey.className
258
- delete propsWithKey.className
259
- }
260
- if (propsWithKey.htmlFor !== undefined) {
261
- propsWithKey.for = propsWithKey.htmlFor
262
- delete propsWithKey.htmlFor
263
- }
264
-
265
- // Preact's onChange fires on every keystroke for form elements (like onInput)
266
- if (
267
- (type === 'input' || type === 'textarea' || type === 'select') &&
268
- propsWithKey.onChange !== undefined
269
- ) {
270
- if (propsWithKey.onInput === undefined) {
271
- propsWithKey.onInput = propsWithKey.onChange
272
- }
273
- delete propsWithKey.onChange
274
- }
275
-
276
- // autoFocus → autofocus
277
- if (propsWithKey.autoFocus !== undefined) {
278
- propsWithKey.autofocus = propsWithKey.autoFocus
279
- delete propsWithKey.autoFocus
280
- }
281
-
282
- // defaultValue / defaultChecked → value / checked when no controlled value
283
- if (type === 'input' || type === 'textarea') {
284
- if (propsWithKey.defaultValue !== undefined && propsWithKey.value === undefined) {
285
- propsWithKey.value = propsWithKey.defaultValue
286
- delete propsWithKey.defaultValue
287
- }
288
- if (propsWithKey.defaultChecked !== undefined && propsWithKey.checked === undefined) {
289
- propsWithKey.checked = propsWithKey.defaultChecked
290
- delete propsWithKey.defaultChecked
291
- }
292
- }
293
-
294
- // Strip Preact-only props that have no DOM equivalent
295
- delete propsWithKey.suppressHydrationWarning
296
- }
254
+ // Map Preact-style attributes to standard HTML attributes.
255
+ // Shared with @pyreon/react-compat see @pyreon/core/compat-shared.
256
+ mapCompatDomProps(propsWithKey, type)
297
257
 
298
258
  return h(type, propsWithKey, ...(childArray as VNodeChild[]))
299
259
  }