ripple 0.4.0 → 0.4.2

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 (40) hide show
  1. package/CHANGELOG.md +82 -0
  2. package/package.json +3 -2
  3. package/src/constants.js +4 -0
  4. package/src/jsx-runtime.d.ts +12 -2
  5. package/src/runtime/internal/client/constants.js +6 -0
  6. package/src/runtime/internal/client/for.js +224 -50
  7. package/src/runtime/internal/client/hydration.js +0 -16
  8. package/src/runtime/internal/client/index.js +2 -2
  9. package/src/runtime/internal/client/operations.js +1 -2
  10. package/src/runtime/internal/client/render.js +42 -4
  11. package/src/runtime/internal/client/runtime.js +45 -2
  12. package/src/runtime/internal/server/index.js +11 -6
  13. package/tests/client/basic/basic.attributes.test.tsrx +37 -0
  14. package/tests/client/compiler/compiler.basic.test.tsrx +2 -2
  15. package/tests/client/for-item.test.tsrx +404 -0
  16. package/tests/hydration/compiled/client/basic.js +29 -55
  17. package/tests/hydration/compiled/client/events.js +80 -67
  18. package/tests/hydration/compiled/client/for.js +95 -80
  19. package/tests/hydration/compiled/client/fragment-cursor.js +412 -344
  20. package/tests/hydration/compiled/client/head.js +4 -7
  21. package/tests/hydration/compiled/client/html.js +40 -64
  22. package/tests/hydration/compiled/client/if-children.js +30 -34
  23. package/tests/hydration/compiled/client/if-fragment-controlflow.js +7 -7
  24. package/tests/hydration/compiled/client/if.js +4 -4
  25. package/tests/hydration/compiled/client/mixed-control-flow.js +20 -50
  26. package/tests/hydration/compiled/client/nested-control-flow.js +97 -185
  27. package/tests/hydration/compiled/client/portal.js +2 -2
  28. package/tests/hydration/compiled/client/reactivity.js +17 -31
  29. package/tests/hydration/compiled/client/streaming.js +4 -8
  30. package/tests/hydration/compiled/client/typed-text.js +4 -15
  31. package/tests/hydration/compiled/server/events.js +5 -53
  32. package/tests/hydration/compiled/server/for.js +1 -9
  33. package/tests/hydration/compiled/server/fragment-cursor.js +36 -324
  34. package/tests/server/basic.attributes.test.tsrx +28 -0
  35. package/tests/server/basic.test.tsrx +23 -0
  36. package/tests/utils/jsx-runtime-types.test.js +67 -2
  37. package/tests/utils/tracked-types.test.js +117 -0
  38. package/types/index.d.ts +7 -8
  39. package/tests/client/compiler/__snapshots__/compiler.assignments.test.rsrx.snap +0 -12
  40. package/tests/client/compiler/__snapshots__/compiler.typescript.test.rsrx.snap +0 -46
package/CHANGELOG.md CHANGED
@@ -1,5 +1,87 @@
1
1
  # ripple
2
2
 
3
+ ## 0.4.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [#1478](https://github.com/Ripple-TS/ripple/pull/1478)
8
+ [`1032539`](https://github.com/Ripple-TS/ripple/commit/10325392e4b1ec7fba78b8ddaf57bc5376adaab1)
9
+ Thanks [@leonidaz](https://github.com/leonidaz)! - Faster buffered server
10
+ rendering. Static text and attribute values are emitted with characters above
11
+ U+00FF as numeric character references (raw-text elements such as `<script>`
12
+ excluded), so a server response stays a one-byte string whenever its dynamic
13
+ data is Latin-1 too: a single static em dash no longer widens the whole body to
14
+ two bytes per character, which halved the flatten, byte-length and UTF-8 encode
15
+ cost of a page. The runtime text escaper checks for `&` and `<` with two
16
+ single-character searches instead of a regex test.
17
+
18
+ - [#1481](https://github.com/Ripple-TS/ripple/pull/1481)
19
+ [`e9382ed`](https://github.com/Ripple-TS/ripple/commit/e9382ed7538779aeb8671b8e3f3fdfd3a897b85a)
20
+ Thanks [@leonidaz](https://github.com/leonidaz)! - Cheaper text-only elements
21
+ and typed loop items. An element whose only child is a typed text expression
22
+ (`<td>{row.name}</td>`) is cloned without a placeholder text node and written
23
+ through the element (`set_text_content`): the first write creates the text node
24
+ with `textContent`, later writes update it in place, and hydration adopts the
25
+ server-rendered text with no cursor descent, which removes a DOM read and a text
26
+ node per cell from every list row. A keyed `@for` key callback reads the item
27
+ directly instead of unwrapping it. Type inference now follows a binding's
28
+ declared type through property writes (`items.value = next` no longer hides
29
+ `track<Row[]>()` from the loop item) and through array and tuple indexing
30
+ (`row.queries[0].elapsed`), so those reads lower to direct text updates in one
31
+ render block per row.
32
+
33
+ - [#1483](https://github.com/Ripple-TS/ripple/pull/1483)
34
+ [`5de359e`](https://github.com/Ripple-TS/ripple/commit/5de359e430391b0e1609795b42d26161fd5c2ff9)
35
+ Thanks [@leonidaz](https://github.com/leonidaz)! - perf: a list item without a
36
+ tracked of its own (a plain list's item, or a local keyed item) is created
37
+ through a lean first run (`run_branch`) instead of the generic block runner:
38
+ fewer checks and no re-run bookkeeping per item.
39
+
40
+ - [#1482](https://github.com/Ripple-TS/ripple/pull/1482)
41
+ [`0030be0`](https://github.com/Ripple-TS/ripple/commit/0030be0aa3c7f1d2ce40500dc57ea980b69c69ec)
42
+ Thanks [@leonidaz](https://github.com/leonidaz)! - perf: cheaper keyed lists. A
43
+ `@for` or `@if` that trails template siblings appends into its parent element
44
+ instead of inserting before a `<!>` placeholder. A list item whose updates live
45
+ in one render block carries that block on the item block itself (`_$_.item`),
46
+ and a keyed item that only its render block reads is held as it is instead of in
47
+ a tracked, re-running its block directly when the key's item is replaced. Leaf
48
+ text is written without a DOM read, from the value the render block last wrote.
49
+ A keyed diff that re-lays most of its items walks the range front to back
50
+ instead of appending every item at the end, about half the reorder cost in
51
+ Chromium and far less right after a layout flush.
52
+ - Updated dependencies
53
+ [[`1032539`](https://github.com/Ripple-TS/ripple/commit/10325392e4b1ec7fba78b8ddaf57bc5376adaab1),
54
+ [`e9382ed`](https://github.com/Ripple-TS/ripple/commit/e9382ed7538779aeb8671b8e3f3fdfd3a897b85a),
55
+ [`0030be0`](https://github.com/Ripple-TS/ripple/commit/0030be0aa3c7f1d2ce40500dc57ea980b69c69ec)]:
56
+ - @tsrx/ripple@0.2.1
57
+
58
+ ## 0.4.1
59
+
60
+ ### Patch Changes
61
+
62
+ - [#1477](https://github.com/Ripple-TS/ripple/pull/1477)
63
+ [`670d669`](https://github.com/Ripple-TS/ripple/commit/670d66916a0b2d58254adb3248abc9d3e816fd8d)
64
+ Thanks [@leonidaz](https://github.com/leonidaz)! - Use property-specific CSS
65
+ types for HTML and SVG style objects and export `CSSProperties` from `ripple`
66
+ and `ripple/jsx-runtime`. Numeric lengths such as `width: 400` now produce a
67
+ type error; specify units with `width: '400px'` or `width: '24rem'`. Unitless
68
+ CSS properties, zero lengths, camelCase and kebab-case names, and CSS custom
69
+ properties remain supported.
70
+
71
+ Style properties set to `null` or `undefined` are omitted during server
72
+ rendering and removed on the client, matching the nullable and optional property
73
+ types and supporting conditional style values. Ripple does not infer or add CSS
74
+ units.
75
+
76
+ Re-export the `JSX` and `Ripple` namespaces as types from `ripple` so element
77
+ prop and event types can be imported from the main package. The
78
+ `ripple/jsx-runtime` exports remain available.
79
+
80
+ - [#1475](https://github.com/Ripple-TS/ripple/pull/1475)
81
+ [`e008b3f`](https://github.com/Ripple-TS/ripple/commit/e008b3f933a5a5b54ca8b74ae80aa98b6ddfb82f)
82
+ Thanks [@leonidaz](https://github.com/leonidaz)! - Show public Tracked, Derived,
83
+ and WritableDerived type names in value property hovers.
84
+
3
85
  ## 0.4.0
4
86
 
5
87
  ### Minor Changes
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Ripple is an elegant TypeScript UI framework",
4
4
  "license": "MIT",
5
5
  "author": "Dominic Gannaway",
6
- "version": "0.4.0",
6
+ "version": "0.4.2",
7
7
  "type": "module",
8
8
  "module": "src/runtime/index-client.js",
9
9
  "main": "src/runtime/index-client.js",
@@ -77,10 +77,11 @@
77
77
  },
78
78
  "dependencies": {
79
79
  "clsx": "^2.1.1",
80
+ "csstype": "^3.2.3",
80
81
  "devalue": "^5.9.2",
81
82
  "esm-env": "^1.2.2",
82
83
  "@tsrx/core": "^0.2.0",
83
- "@tsrx/ripple": "0.2.0"
84
+ "@tsrx/ripple": "0.2.1"
84
85
  },
85
86
  "devDependencies": {
86
87
  "@types/estree": "^1.0.8",
package/src/constants.js CHANGED
@@ -6,6 +6,10 @@ export const IS_INDEXED = 1 << 3;
6
6
  // `__anchor` (sibling semantics, no `<!>` wrapper). Distinct from IS_CONTROLLED,
7
7
  // which renders inside a parent element.
8
8
  export const ROOT_CONTROLLED = 1 << 4;
9
+ // A keyed @for whose item is read only by the render block its item block
10
+ // carries: items are held as they are, not in a tracked, and a replaced item
11
+ // re-runs its block directly (see the runtime's `item`).
12
+ export const LOCAL_ITEMS = 1 << 7;
9
13
  export const TEMPLATE_SVG_NAMESPACE = 1 << 5;
10
14
  export const TEMPLATE_MATHML_NAMESPACE = 1 << 6;
11
15
 
@@ -7,6 +7,7 @@ import type {
7
7
  TSRXElement,
8
8
  } from '#public';
9
9
  import type { Nullable } from '@tsrx/core/types/helpers';
10
+ import type * as CSS from 'csstype';
10
11
  export type { RefValue } from '#public';
11
12
 
12
13
  /**
@@ -50,10 +51,18 @@ export function jsxs(
50
51
  */
51
52
  export function Fragment(props: FragmentProps): TSRXElement;
52
53
 
54
+ type NullableStyleProperties<T> = { [Property in keyof T]: T[Property] | null };
55
+
53
56
  /** JSX attributes live under Ripple so editor hovers identify their framework. */
54
57
  declare namespace Ripple {
55
58
  type ClassValue = string | import('clsx').ClassArray | import('clsx').ClassDictionary;
56
59
 
60
+ /** Inline CSS styles. Values keep their units; null and undefined remove a property. */
61
+ interface CSSProperties
62
+ extends NullableStyleProperties<CSS.Properties>, NullableStyleProperties<CSS.PropertiesHyphen> {
63
+ [property: `--${string}`]: string | number | null | undefined;
64
+ }
65
+
57
66
  type Event<
58
67
  Target extends globalThis.EventTarget,
59
68
  EventType extends globalThis.Event,
@@ -493,7 +502,7 @@ declare namespace Ripple {
493
502
  class?: ClassValue | undefined | null;
494
503
  className?: Nullable<string>;
495
504
  id?: Nullable<string>;
496
- style?: Nullable<string> | Record<string, string | number>;
505
+ style?: Nullable<string> | CSSProperties;
497
506
  title?: Nullable<string>;
498
507
  lang?: Nullable<string>;
499
508
  dir?: 'ltr' | 'rtl' | 'auto';
@@ -627,7 +636,7 @@ declare namespace Ripple {
627
636
  // Styling
628
637
  class?: ClassValue | undefined | null;
629
638
  className?: Nullable<string>;
630
- style?: Nullable<string> | Record<string, string | number>;
639
+ style?: Nullable<string> | CSSProperties;
631
640
 
632
641
  // Presentation attributes
633
642
  alignmentBaseline?:
@@ -1405,6 +1414,7 @@ declare namespace Ripple {
1405
1414
  }
1406
1415
 
1407
1416
  export import ClassValue = Ripple.ClassValue;
1417
+ export import CSSProperties = Ripple.CSSProperties;
1408
1418
  export import JSX = Ripple.JSX;
1409
1419
  export { Ripple };
1410
1420
 
@@ -29,6 +29,12 @@ export var SELECTOR = 1 << 23;
29
29
  export var RELEASED = 1 << 24;
30
30
  /** A block whose latest run created deriveds that are recorded for release (see `release_deriveds`). */
31
31
  export var CREATES_DERIVEDS = 1 << 25;
32
+ /**
33
+ * A list item block that carries its body's render block itself (see the
34
+ * runtime's `item`): a branch block for its DOM range, and a reaction that
35
+ * re-runs the body's update function.
36
+ */
37
+ export var ITEM_BLOCK = 1 << 26;
32
38
 
33
39
  export var CONTROL_FLOW_BLOCK = FOR_BLOCK | IF_BLOCK | SWITCH_BLOCK | TRY_BLOCK | COMPOSITE_BLOCK;
34
40