ripple 0.3.13 → 0.3.14

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 (66) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/package.json +5 -30
  3. package/src/runtime/array.js +38 -38
  4. package/src/runtime/create-subscriber.js +2 -2
  5. package/src/runtime/internal/client/bindings.js +4 -6
  6. package/src/runtime/internal/client/events.js +8 -3
  7. package/src/runtime/internal/client/hmr.js +5 -17
  8. package/src/runtime/internal/client/runtime.js +1 -0
  9. package/src/runtime/internal/server/blocks.js +7 -9
  10. package/src/runtime/internal/server/index.js +14 -22
  11. package/src/runtime/media-query.js +34 -33
  12. package/src/runtime/object.js +7 -10
  13. package/src/runtime/proxy.js +2 -3
  14. package/src/runtime/reactive-value.js +23 -21
  15. package/src/utils/ast.js +1 -1
  16. package/src/utils/attributes.js +43 -0
  17. package/src/utils/builders.js +2 -2
  18. package/tests/client/basic/basic.errors.test.rsrx +1 -1
  19. package/tests/client/basic/basic.styling.test.rsrx +1 -1
  20. package/tests/client/compiler/compiler.assignments.test.rsrx +1 -1
  21. package/tests/client/compiler/compiler.attributes.test.rsrx +1 -1
  22. package/tests/client/compiler/compiler.basic.test.rsrx +13 -13
  23. package/tests/client/compiler/compiler.tracked-access.test.rsrx +1 -1
  24. package/tests/client/compiler/compiler.try-in-function.test.rsrx +1 -1
  25. package/tests/client/compiler/compiler.typescript.test.rsrx +1 -1
  26. package/tests/client/css/global-additional-cases.test.rsrx +1 -1
  27. package/tests/client/css/global-advanced-selectors.test.rsrx +1 -1
  28. package/tests/client/css/global-at-rules.test.rsrx +1 -1
  29. package/tests/client/css/global-basic.test.rsrx +1 -1
  30. package/tests/client/css/global-classes-ids.test.rsrx +1 -1
  31. package/tests/client/css/global-combinators.test.rsrx +1 -1
  32. package/tests/client/css/global-complex-nesting.test.rsrx +1 -1
  33. package/tests/client/css/global-edge-cases.test.rsrx +1 -1
  34. package/tests/client/css/global-keyframes.test.rsrx +1 -1
  35. package/tests/client/css/global-nested.test.rsrx +1 -1
  36. package/tests/client/css/global-pseudo.test.rsrx +1 -1
  37. package/tests/client/css/global-scoping.test.rsrx +1 -1
  38. package/tests/client/css/style-identifier.test.rsrx +1 -1
  39. package/tests/client/return.test.rsrx +1 -1
  40. package/tests/hydration/build-components.js +1 -1
  41. package/tests/server/style-identifier.test.rsrx +1 -1
  42. package/tests/setup-server.js +1 -1
  43. package/tests/utils/compiler-compat-config.test.js +1 -1
  44. package/src/compiler/comment-utils.js +0 -91
  45. package/src/compiler/errors.js +0 -77
  46. package/src/compiler/identifier-utils.js +0 -80
  47. package/src/compiler/index.d.ts +0 -127
  48. package/src/compiler/index.js +0 -89
  49. package/src/compiler/phases/1-parse/index.js +0 -3007
  50. package/src/compiler/phases/1-parse/style.js +0 -704
  51. package/src/compiler/phases/2-analyze/css-analyze.js +0 -160
  52. package/src/compiler/phases/2-analyze/index.js +0 -2208
  53. package/src/compiler/phases/2-analyze/prune.js +0 -1131
  54. package/src/compiler/phases/2-analyze/validation.js +0 -168
  55. package/src/compiler/phases/3-transform/client/index.js +0 -5264
  56. package/src/compiler/phases/3-transform/segments.js +0 -2125
  57. package/src/compiler/phases/3-transform/server/index.js +0 -1749
  58. package/src/compiler/phases/3-transform/stylesheet.js +0 -545
  59. package/src/compiler/scope.js +0 -476
  60. package/src/compiler/source-map-utils.js +0 -358
  61. package/src/compiler/types/acorn.d.ts +0 -11
  62. package/src/compiler/types/estree-jsx.d.ts +0 -11
  63. package/src/compiler/types/estree.d.ts +0 -11
  64. package/src/compiler/types/index.d.ts +0 -1411
  65. package/src/compiler/types/parse.d.ts +0 -1723
  66. package/src/compiler/utils.js +0 -1258
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # ripple
2
2
 
3
+ ## 0.3.14
4
+
5
+ ### Patch Changes
6
+
7
+ - [#866](https://github.com/Ripple-TS/ripple/pull/866)
8
+ [`228f1bb`](https://github.com/Ripple-TS/ripple/commit/228f1bb36cd3e8506c422ed0997164bf5a0b5fe2)
9
+ Thanks [@trueadm](https://github.com/trueadm)! - Extract compiler into
10
+ `@tsrx/core` and `@tsrx/ripple` packages
11
+ - `@tsrx/core`: Core compiler infrastructure — parser factory, scope management,
12
+ utilities, constants, and type definitions
13
+ - `@tsrx/ripple`: Ripple-specific compiler — RipplePlugin, analyze,
14
+ client/server transforms
15
+ - Remove compiler source code from `ripple` package (consumers should use
16
+ `@tsrx/ripple`)
17
+ - Migrate eslint-plugin type imports to `@tsrx/core/types/*`
18
+ - Remove unused compiler dependencies from `ripple` package
19
+
20
+ - Updated dependencies
21
+ [[`228f1bb`](https://github.com/Ripple-TS/ripple/commit/228f1bb36cd3e8506c422ed0997164bf5a0b5fe2)]:
22
+ - ripple@0.3.14
23
+
3
24
  ## 0.3.13
4
25
 
5
26
  ### Patch 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.3.13",
6
+ "version": "0.3.14",
7
7
  "type": "module",
8
8
  "module": "src/runtime/index-client.js",
9
9
  "main": "src/runtime/index-client.js",
@@ -33,29 +33,12 @@
33
33
  "types": "./types/server.d.ts",
34
34
  "default": "./src/server/index.js"
35
35
  },
36
- "./compiler": {
37
- "types": "./src/compiler/index.d.ts",
38
- "require": "./src/compiler/index.js",
39
- "default": "./src/compiler/index.js"
40
- },
41
- "./types/estree": {
42
- "types": "./src/compiler/types/estree.d.ts"
43
- },
44
- "./types/estree-jsx": {
45
- "types": "./src/compiler/types/estree-jsx.d.ts"
46
- },
47
- "./types/acorn": {
48
- "types": "./src/compiler/types/acorn.d.ts"
49
- },
50
36
  "./compiler/internal/import": {
51
37
  "types": "./src/compiler/types/import.d.ts"
52
38
  },
53
39
  "./compiler/internal/rpc": {
54
40
  "types": "./src/compiler/types/rpc.d.ts"
55
41
  },
56
- "./compiler/internal/identifier/utils": {
57
- "default": "./src/compiler/identifier-utils.js"
58
- },
59
42
  "./validator": {
60
43
  "types": "./types/index.d.ts",
61
44
  "require": "./validator/index.js",
@@ -83,23 +66,13 @@
83
66
  "#client": "./src/runtime/internal/client/types.d.ts",
84
67
  "#client/constants": "./src/internal/client/constants.js",
85
68
  "#server": "./src/runtime/internal/server/types.d.ts",
86
- "#compiler": "./src/compiler/types/index.d.ts",
87
- "#parser": "./src/compiler/types/parse.d.ts",
88
69
  "#public": "./types/index.d.ts",
89
70
  "#helpers": "./src/helpers.d.ts"
90
71
  },
91
72
  "dependencies": {
92
- "@jridgewell/sourcemap-codec": "^1.5.5",
93
- "@sveltejs/acorn-typescript": "^1.0.9",
94
- "acorn": "^8.15.0",
95
73
  "clsx": "^2.1.1",
96
74
  "devalue": "^5.6.3",
97
75
  "esm-env": "^1.2.2",
98
- "esrap": "^2.1.0",
99
- "is-reference": "^3.0.3",
100
- "magic-string": "^0.30.18",
101
- "muggle-string": "^0.4.1",
102
- "zimmerframe": "^1.1.2",
103
76
  "@types/estree": "^1.0.8",
104
77
  "@types/estree-jsx": "^1.0.5"
105
78
  },
@@ -108,9 +81,11 @@
108
81
  "@typescript-eslint/types": "^8.40.0",
109
82
  "typescript": "^5.9.3",
110
83
  "@volar/language-core": "~2.4.28",
111
- "vscode-languageserver-types": "^3.17.5"
84
+ "vscode-languageserver-types": "^3.17.5",
85
+ "@tsrx/core": "0.0.2",
86
+ "@tsrx/ripple": "0.0.2"
112
87
  },
113
88
  "peerDependencies": {
114
- "ripple": "0.3.13"
89
+ "ripple": "0.3.14"
115
90
  }
116
91
  }
@@ -4,49 +4,49 @@ import { array_proxy } from './proxy.js';
4
4
 
5
5
  /**
6
6
  * @template T
7
- * @constructor
8
- * @param {...T} elements
9
- * @returns {RippleArray<T>}
10
7
  */
11
- export function RippleArray(...elements) {
12
- if (!new.target) {
13
- throw new Error("RippleArray must be called with 'new'");
8
+ export class RippleArray {
9
+ /**
10
+ * @param {...T} elements
11
+ */
12
+ constructor(...elements) {
13
+ var block = safe_scope();
14
+ return /** @type {RippleArray<any>} */ (
15
+ /** @type {unknown} */ (ripple_array(block, ...elements))
16
+ );
14
17
  }
15
18
 
16
- var block = safe_scope();
17
- return ripple_array(block, ...elements);
18
- }
19
-
20
- /**
21
- * @template T
22
- * @param {ArrayLike<T> | Iterable<T>} arrayLike
23
- * @param {(v: T, k: number) => any | undefined} [mapFn]
24
- * @param {*} [thisArg]
25
- * @returns {RippleArray<T>}
26
- */
27
- RippleArray.from = function (arrayLike, mapFn, thisArg) {
28
- return ripple_array.from(safe_scope(), arrayLike, mapFn, thisArg);
29
- };
19
+ /**
20
+ * @template U
21
+ * @param {ArrayLike<U> | Iterable<U>} arrayLike
22
+ * @param {(v: U, k: number) => any | undefined} [mapFn]
23
+ * @param {*} [thisArg]
24
+ * @returns {RippleArray<U>}
25
+ */
26
+ static from(arrayLike, mapFn, thisArg) {
27
+ return ripple_array.from(safe_scope(), arrayLike, mapFn, thisArg);
28
+ }
30
29
 
31
- /**
32
- * @template T
33
- * @param {...T} items
34
- * @returns {RippleArray<T>}
35
- */
36
- RippleArray.of = function (...items) {
37
- return ripple_array.of(safe_scope(), ...items);
38
- };
30
+ /**
31
+ * @template U
32
+ * @param {...U} items
33
+ * @returns {RippleArray<U>}
34
+ */
35
+ static of(...items) {
36
+ return ripple_array.of(safe_scope(), ...items);
37
+ }
39
38
 
40
- /**
41
- * @template T
42
- * @param {ArrayLike<T> | Iterable<T>} arrayLike
43
- * @param {(v: T, k: number) => any | undefined} [mapFn]
44
- * @param {any} [thisArg]
45
- * @returns {Promise<RippleArray<T>>}
46
- */
47
- RippleArray.fromAsync = async function (arrayLike, mapFn, thisArg) {
48
- return ripple_array.fromAsync(safe_scope(), arrayLike, mapFn, thisArg);
49
- };
39
+ /**
40
+ * @template U
41
+ * @param {ArrayLike<U> | Iterable<U>} arrayLike
42
+ * @param {(v: U, k: number) => any | undefined} [mapFn]
43
+ * @param {any} [thisArg]
44
+ * @returns {Promise<RippleArray<U>>}
45
+ */
46
+ static async fromAsync(arrayLike, mapFn, thisArg) {
47
+ return ripple_array.fromAsync(safe_scope(), arrayLike, mapFn, thisArg);
48
+ }
49
+ }
50
50
 
51
51
  /**
52
52
  * @template T
@@ -1,8 +1,8 @@
1
- /** @import { createSubscriber } from '#public' */
1
+ /** @import { createSubscriber as createSubscriberType } from '#public' */
2
2
  import { untrack, queue_microtask } from './internal/client/runtime.js';
3
3
  import { effect } from './internal/client/blocks.js';
4
4
 
5
- /** @type {createSubscriber} */
5
+ /** @type {typeof createSubscriberType} */
6
6
  export function createSubscriber(start) {
7
7
  let subscribers = 0;
8
8
  /** @type {(() => void) | void} */
@@ -1,11 +1,9 @@
1
1
  /** @import { Tracked } from '#client' */
2
2
 
3
- /**
4
- @typedef {(v: unknown) => void} SetFunction
5
- @typedef {() => any} BindGetter
6
- @typedef {(v: unknown) => void} BindSetter
7
- @typedef {{getter: BindGetter, setter: BindSetter}} BindGetSet
8
- */
3
+ /** @typedef {(v: unknown) => void} SetFunction */
4
+ /** @typedef {() => any} BindGetter */
5
+ /** @typedef {(v: unknown) => void} BindSetter */
6
+ /** @typedef {{getter: BindGetter, setter: BindSetter}} BindGetSet */
9
7
 
10
8
  import { effect, render } from './blocks.js';
11
9
  import { on } from './events.js';
@@ -277,8 +277,9 @@ function create_event(event_name, dom, handler, options) {
277
277
  }
278
278
 
279
279
  /**
280
- * @type {EventListener}
281
280
  * @this {Element}
281
+ * @param {Event} event
282
+ * @returns {any}
282
283
  */
283
284
  function target_handler(event) {
284
285
  var previous_block = active_block;
@@ -295,7 +296,7 @@ function create_event(event_name, dom, handler, options) {
295
296
  handle_event_propagation.call(dom, event);
296
297
  }
297
298
  if (!event.cancelBubble) {
298
- return handler?.call(this, event);
299
+ return handler?.call(/** @type {Element} */ (this), event);
299
300
  }
300
301
  } finally {
301
302
  set_active_block(previous_block);
@@ -380,6 +381,7 @@ export function delegate(events) {
380
381
 
381
382
  /** @param {Element} target */
382
383
  export function handle_root_events(target) {
384
+ /** @type {Set<string>} */
383
385
  var registered_events = new Set();
384
386
  root_target = target;
385
387
 
@@ -417,7 +419,10 @@ export function handle_root_events(target) {
417
419
 
418
420
  return () => {
419
421
  for (var event_name of registered_events) {
420
- target.removeEventListener(event_name, handle_event_propagation);
422
+ target.removeEventListener(
423
+ event_name,
424
+ /** @type {EventListener} */ (handle_event_propagation),
425
+ );
421
426
  }
422
427
  root_event_handles.delete(event_handle);
423
428
  root_target = null;
@@ -6,21 +6,9 @@ import { hydrate_node, hydrating } from './hydration.js';
6
6
  import { branch, destroy_block, render } from './blocks.js';
7
7
  import { active_block, get, set, tracked } from './runtime.js';
8
8
 
9
- /**
10
- @typedef {
11
- (anchor: Node, props: any, block: Block | null) => void
12
- } Component
13
-
14
- @typedef {
15
- Component & {
16
- [HMR]: {
17
- fn: Component;
18
- current: Tracked | undefined;
19
- update: (incoming: ComponentWrapper) => void;
20
- }
21
- }
22
- } ComponentWrapper
23
- */
9
+ /** @typedef {(anchor: Node, props: any, block: Block | null) => void} Component */
10
+
11
+ /** @typedef {Component & { [HMR]: { fn: Component; current: Tracked | undefined; update: (incoming: ComponentWrapper) => void; } }} ComponentWrapper */
24
12
 
25
13
  /**
26
14
  * Wraps a component function for HMR (Hot Module Replacement).
@@ -35,10 +23,9 @@ export function hmr(fn) {
35
23
  var current;
36
24
 
37
25
  /**
38
- * @type {ComponentWrapper}
39
26
  * @param {Node} anchor
40
27
  * @param {any} props
41
- * @param {Block | null} block
28
+ * @param {Block | null} [block]
42
29
  */
43
30
  function wrapper(anchor, props, block = active_block) {
44
31
  if (current === undefined) {
@@ -88,6 +75,7 @@ export function hmr(fn) {
88
75
  wrapper[HMR] = {
89
76
  fn,
90
77
  current,
78
+ /** @param {ComponentWrapper} incoming */
91
79
  update: (incoming) => {
92
80
  fn = incoming[HMR].fn;
93
81
  wrapper[HMR].fn = fn;
@@ -394,6 +394,7 @@ class TrackedValue {
394
394
  this.a = a;
395
395
  this.b = block;
396
396
  this.c = 0;
397
+ /** @type {DeferredTrackedEntry[] | null} */
397
398
  this.d = null;
398
399
  this.f = TRACKED;
399
400
  this.__v = v;
@@ -1,15 +1,13 @@
1
1
  /**
2
- @import { Block, TryBlock, TryBlockWithCatch } from '#server';
3
- @import { OutputInterface } from './index.js';
2
+ * @import { Block, TryBlock, TryBlockWithCatch } from '#server';
3
+ * @import { OutputInterface } from './index.js';
4
4
  */
5
5
 
6
- /**
7
- @typedef {Error} SSRError
8
- @typedef {(__output: OutputInterface) => void} BlockFunction
9
- @typedef {() => void} TryFunction
10
- @typedef {(error: SSRError) => void} CatchFunction
11
- @typedef {() => void} PendingFunction
12
- */
6
+ /** @typedef {Error} SSRError */
7
+ /** @typedef {(__output: OutputInterface) => void} BlockFunction */
8
+ /** @typedef {() => void} TryFunction */
9
+ /** @typedef {(error: SSRError) => void} CatchFunction */
10
+ /** @typedef {() => void} PendingFunction */
13
11
 
14
12
  import { ASYNC_DERIVED_READ_THROWN } from '../client/constants.js';
15
13
  import {
@@ -1,29 +1,17 @@
1
1
  /**
2
- @import { Component, Dependency, Derived, Tracked, Block, TryBlockWithCatch } from '#server';
3
- @import { NestedArray } from '#helpers';
4
- @import { Props } from '#public';
5
- @import { RenderResult, BaseRenderOptions, RenderStreamResult, Stream, StreamSink } from 'ripple/server';
6
- */
2
+ * @import { Component, Dependency, Derived, Tracked, Block, TryBlockWithCatch } from '#server';
3
+ * @import { NestedArray } from '#helpers';
4
+ * @import { Props } from '#public';
5
+ * @import { RenderResult, BaseRenderOptions, RenderStreamResult, Stream, StreamSink } from 'ripple/server';
6
+ */
7
7
 
8
8
  // Export-only Types
9
- /**
10
- @typedef {Output} OutputInterface;
11
- */
9
+ /** @typedef {Output} OutputInterface */
12
10
 
13
11
  // Internal Types
14
- /**
15
- @typedef {(props?: Props) => void} RenderComponent
16
- @typedef {{
17
- tag: string;
18
- parent: undefined | ElementContext;
19
- filename: undefined | string;
20
- line: number;
21
- column: number;
22
- }} ElementContext;
23
- @typedef {{
24
- cancel: () => void,
25
- }} RegisteredAsyncOperation;
26
- */
12
+ /** @typedef {(props?: Props) => void} RenderComponent */
13
+ /** @typedef {{ tag: string; parent: undefined | ElementContext; filename: undefined | string; line: number; column: number; }} ElementContext */
14
+ /** @typedef {{ cancel: () => void }} RegisteredAsyncOperation */
27
15
 
28
16
  import {
29
17
  DERIVED,
@@ -36,7 +24,7 @@ import {
36
24
  } from '../client/constants.js';
37
25
  import { is_ripple_object, array_slice } from '../client/utils.js';
38
26
  import { escape } from '../../../utils/escaping.js';
39
- import { is_boolean_attribute } from '../../../compiler/utils.js';
27
+ import { is_boolean_attribute } from '../../../utils/attributes.js';
40
28
  import { clsx } from 'clsx';
41
29
  import { normalize_css_property_name } from '../../../utils/normalize_css_property_name.js';
42
30
  import { BLOCK_CLOSE, BLOCK_OPEN } from '../../../constants.js';
@@ -586,6 +574,7 @@ export async function render(component, passed_in_options = {}) {
586
574
  var top_level_error = null;
587
575
  var head = '';
588
576
  var body = '';
577
+ /** @type {Set<string>} */
589
578
  var css = new Set();
590
579
  /** @type {Block | null} */
591
580
  var root_block = null;
@@ -977,7 +966,9 @@ class TrackedValue {
977
966
  */
978
967
  constructor(v, a) {
979
968
  this.a = a;
969
+ /** @type {AbortController | null} */
980
970
  this.aa = null;
971
+ /** @type {PromiseLike<any> | null} */
981
972
  this.ap = null;
982
973
  this.c = 0;
983
974
  this.f = TRACKED;
@@ -1022,6 +1013,7 @@ class DerivedValue {
1022
1013
  this.b = /** @type {Block} */ (active_block);
1023
1014
  this.c = 0;
1024
1015
  this.co = active_component;
1016
+ /** @type {Dependency | null} */
1025
1017
  this.d = null;
1026
1018
  this.f = DERIVED;
1027
1019
  this.fn = fn;
@@ -2,47 +2,48 @@ import { on } from './internal/client/events.js';
2
2
  import { get, safe_scope, set, tracked, with_scope } from './internal/client/index.js';
3
3
  import { ReactiveValue } from './reactive-value.js';
4
4
 
5
+ /** @typedef {import('#public').ReactiveValue<boolean>} ReactiveValueBoolean */
6
+
5
7
  const parenthesis_regex = /\(.+\)/;
6
8
  const non_parenthesized_keywords = new Set(['all', 'print', 'screen', 'and', 'or', 'not', 'only']);
7
9
 
8
10
  /**
9
- * @constructor
10
- * @param {string} query
11
- * @param {boolean | undefined} [fallback]
12
- * @returns {ReactiveValue<boolean>}
11
+ * @type {new (query: string, fallback?: boolean | undefined) => ReactiveValueBoolean}
13
12
  */
14
- export function MediaQuery(query, fallback) {
15
- if (!new.target) {
16
- throw new TypeError('MediaQuery must be called with new');
17
- }
13
+ export const MediaQuery = /** @type {any} */ (
14
+ function MediaQuery(/** @type {string} */ query, /** @type {boolean | undefined} */ fallback) {
15
+ if (!new.target) {
16
+ throw new TypeError('MediaQuery must be called with new');
17
+ }
18
18
 
19
- var block = safe_scope();
19
+ var block = safe_scope();
20
20
 
21
- let final_query =
22
- parenthesis_regex.test(query) ||
23
- // we need to use `some` here because technically this `window.matchMedia('random,screen')` still returns true
24
- query.split(/[\s,]+/).some((keyword) => non_parenthesized_keywords.has(keyword.trim()))
25
- ? query
26
- : `(${query})`;
27
- const q = window.matchMedia(final_query);
28
- const matches = tracked(q.matches, block);
21
+ let final_query =
22
+ parenthesis_regex.test(query) ||
23
+ // we need to use `some` here because technically this `window.matchMedia('random,screen')` still returns true
24
+ query.split(/[\s,]+/).some((keyword) => non_parenthesized_keywords.has(keyword.trim()))
25
+ ? query
26
+ : `(${query})`;
27
+ const q = window.matchMedia(final_query);
28
+ const matches = tracked(q.matches, block);
29
29
 
30
- return new ReactiveValue(
31
- () => get(matches),
32
- () =>
33
- on(
34
- q,
35
- 'change',
36
- () => {
37
- // skip wrapping in untrack as createSubscriber already does it
38
- if (q.matches !== get(matches)) {
39
- set(matches, q.matches);
40
- }
41
- },
42
- { delegated: false },
43
- ),
44
- );
45
- }
30
+ return new ReactiveValue(
31
+ () => get(matches),
32
+ () =>
33
+ on(
34
+ q,
35
+ 'change',
36
+ () => {
37
+ // skip wrapping in untrack as createSubscriber already does it
38
+ if (q.matches !== get(matches)) {
39
+ set(matches, q.matches);
40
+ }
41
+ },
42
+ { delegated: false },
43
+ ),
44
+ );
45
+ }
46
+ );
46
47
 
47
48
  /**
48
49
  * @param {import('#client').Block} block
@@ -4,18 +4,15 @@ import { object_proxy } from './proxy.js';
4
4
 
5
5
  /**
6
6
  * @template {object} T
7
- * @constructor
8
- * @param {T} obj
9
- * @returns {RippleObject<T>}
10
7
  */
11
- export function RippleObject(obj) {
12
- if (!new.target) {
13
- throw new Error("RippleObject must be called with 'new'");
8
+ export class RippleObject {
9
+ /**
10
+ * @param {T} obj
11
+ */
12
+ constructor(obj) {
13
+ var block = safe_scope();
14
+ return /** @type {RippleObject<any>} */ (/** @type {unknown} */ (ripple_object(block, obj)));
14
15
  }
15
-
16
- var block = safe_scope();
17
-
18
- return ripple_object(block, obj);
19
16
  }
20
17
 
21
18
  /**
@@ -1,6 +1,5 @@
1
1
  /** @import { Block, Tracked } from '#client' */
2
- /** @import { RippleArray } from './array.js' */
3
- /** @import { RippleObject } from './object.js' */
2
+ /** @import { RippleArray, RippleObject } from '#public' */
4
3
 
5
4
  import { get, set, tracked } from './internal/client/runtime.js';
6
5
  import {
@@ -295,7 +294,7 @@ export function array_proxy({ elements, block, from_static = false, use_array =
295
294
  arr = new Array(...elements);
296
295
  }
297
296
 
298
- return proxy(arr, block);
297
+ return /** @type {RippleArray<T>} */ (proxy(arr, block));
299
298
  }
300
299
 
301
300
  /**
@@ -1,29 +1,31 @@
1
1
  /** @import { Derived } from '#client' */
2
+ /** @import { ReactiveValue as ReactiveValueT } from '#public' */
2
3
  import { createSubscriber } from './create-subscriber.js';
3
4
  import { safe_scope, derived } from './internal/client/runtime.js';
4
5
 
5
6
  /**
6
- * @template V
7
- * @constructor
8
- * @param {() => V} fn
9
- * @param {() => void | (() => void)} start
10
- * @returns {Derived}
7
+ * @type {new <V>(fn: () => V, start: () => void | (() => void)) => ReactiveValueT<V>}
11
8
  */
12
- export function ReactiveValue(fn, start) {
13
- if (!new.target) {
14
- throw new TypeError('`ReactiveValue` must be called with new');
15
- }
9
+ export const ReactiveValue = /** @type {any} */ (
10
+ function ReactiveValue(
11
+ /** @type {() => any} */ fn,
12
+ /** @type {() => void | (() => void)} */ start,
13
+ ) {
14
+ if (!new.target) {
15
+ throw new TypeError('`ReactiveValue` must be called with new');
16
+ }
16
17
 
17
- const s = createSubscriber(start);
18
- const block = safe_scope();
18
+ const s = createSubscriber(start);
19
+ const block = safe_scope();
19
20
 
20
- return derived(
21
- fn,
22
- block,
23
- () => {
24
- s();
25
- return fn();
26
- },
27
- (_, prev) => prev,
28
- );
29
- }
21
+ return derived(
22
+ fn,
23
+ block,
24
+ () => {
25
+ s();
26
+ return fn();
27
+ },
28
+ (/** @type {any} */ _, /** @type {any} */ prev) => prev,
29
+ );
30
+ }
31
+ );
package/src/utils/ast.js CHANGED
@@ -1,4 +1,4 @@
1
- /** @import * as AST from 'estree' */
1
+ /** @import * as AST from '@tsrx/core/types/estree' */
2
2
 
3
3
  /**
4
4
  * Represents the path of a destructured assignment from either a declaration
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Attributes that are boolean, i.e. they are present or not present.
3
+ */
4
+ const DOM_BOOLEAN_ATTRIBUTES = [
5
+ 'allowfullscreen',
6
+ 'async',
7
+ 'autofocus',
8
+ 'autoplay',
9
+ 'checked',
10
+ 'controls',
11
+ 'default',
12
+ 'disabled',
13
+ 'formnovalidate',
14
+ 'hidden',
15
+ 'indeterminate',
16
+ 'inert',
17
+ 'ismap',
18
+ 'loop',
19
+ 'multiple',
20
+ 'muted',
21
+ 'nomodule',
22
+ 'novalidate',
23
+ 'open',
24
+ 'playsinline',
25
+ 'readonly',
26
+ 'required',
27
+ 'reversed',
28
+ 'seamless',
29
+ 'selected',
30
+ 'webkitdirectory',
31
+ 'defer',
32
+ 'disablepictureinpicture',
33
+ 'disableremoteplayback',
34
+ ];
35
+
36
+ /**
37
+ * Returns true if name is a boolean DOM attribute
38
+ * @param {string} name
39
+ * @returns {boolean}
40
+ */
41
+ export function is_boolean_attribute(name) {
42
+ return DOM_BOOLEAN_ATTRIBUTES.includes(name);
43
+ }
@@ -1,5 +1,5 @@
1
- /** @import * as AST from 'estree' */
2
- /** @import * as ESTreeJSX from 'estree-jsx' */
1
+ /** @import * as AST from '@tsrx/core/types/estree' */
2
+ /** @import * as ESTreeJSX from '@tsrx/core/types/estree-jsx' */
3
3
 
4
4
  import { regex_is_valid_identifier } from './patterns.js';
5
5
  import { sanitize_template_string } from './sanitize_template_string.js';
@@ -1,5 +1,5 @@
1
1
  import { flushSync, track, untrack } from 'ripple';
2
- import { compile } from 'ripple/compiler';
2
+ import { compile } from '@tsrx/ripple';
3
3
 
4
4
  describe('basic client > errors', () => {
5
5
  it('renders with error handling simulation', () => {