ripple 0.3.12 → 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.
- package/CHANGELOG.md +57 -0
- package/package.json +11 -30
- package/src/compiler/types/import.d.ts +0 -12
- package/src/helpers.d.ts +2 -0
- package/src/runtime/array.js +38 -38
- package/src/runtime/create-subscriber.js +2 -2
- package/src/runtime/index-client.js +15 -13
- package/src/runtime/index-server.js +18 -11
- package/src/runtime/internal/client/bindings.js +4 -6
- package/src/runtime/internal/client/blocks.js +19 -23
- package/src/runtime/internal/client/constants.js +20 -9
- package/src/runtime/internal/client/events.js +8 -3
- package/src/runtime/internal/client/hmr.js +5 -17
- package/src/runtime/internal/client/index.js +14 -4
- package/src/runtime/internal/client/runtime.js +436 -173
- package/src/runtime/internal/client/try.js +334 -156
- package/src/runtime/internal/client/types.d.ts +26 -0
- package/src/runtime/internal/server/blocks.js +181 -0
- package/src/runtime/internal/server/constants.js +7 -0
- package/src/runtime/internal/server/index.js +774 -150
- package/src/runtime/internal/server/types.d.ts +35 -0
- package/src/runtime/media-query.js +34 -33
- package/src/runtime/object.js +7 -10
- package/src/runtime/proxy.js +2 -3
- package/src/runtime/reactive-value.js +23 -21
- package/src/server/index.js +1 -1
- package/src/utils/ast.js +1 -1
- package/src/utils/async.js +35 -0
- package/src/utils/attributes.js +43 -0
- package/src/utils/builders.js +5 -3
- package/tests/client/__snapshots__/computed-properties.test.rsrx.snap +49 -0
- package/tests/client/__snapshots__/for.test.rsrx.snap +319 -0
- package/tests/client/__snapshots__/html.test.rsrx.snap +40 -0
- package/tests/client/_etc.test.rsrx +7 -0
- package/tests/client/array/{array.static.test.ripple → array.static.test.rsrx} +18 -20
- package/tests/client/async-suspend.test.rsrx +662 -0
- package/tests/client/basic/__snapshots__/basic.attributes.test.rsrx.snap +60 -0
- package/tests/client/basic/__snapshots__/basic.rendering.test.rsrx.snap +59 -0
- package/tests/client/basic/{basic.errors.test.ripple → basic.errors.test.rsrx} +3 -3
- package/tests/client/basic/{basic.styling.test.ripple → basic.styling.test.rsrx} +1 -1
- package/tests/client/compiler/__snapshots__/compiler.assignments.test.rsrx.snap +12 -0
- package/tests/client/compiler/__snapshots__/compiler.typescript.test.rsrx.snap +46 -0
- package/tests/client/compiler/{compiler.assignments.test.ripple → compiler.assignments.test.rsrx} +1 -1
- package/tests/client/compiler/{compiler.attributes.test.ripple → compiler.attributes.test.rsrx} +1 -1
- package/tests/client/compiler/{compiler.basic.test.ripple → compiler.basic.test.rsrx} +13 -13
- package/tests/client/compiler/{compiler.tracked-access.test.ripple → compiler.tracked-access.test.rsrx} +1 -1
- package/tests/client/compiler/{compiler.try-in-function.test.ripple → compiler.try-in-function.test.rsrx} +9 -7
- package/tests/client/compiler/{compiler.typescript.test.ripple → compiler.typescript.test.rsrx} +1 -1
- package/tests/client/composite/__snapshots__/composite.render.test.rsrx.snap +37 -0
- package/tests/client/css/{global-additional-cases.test.ripple → global-additional-cases.test.rsrx} +1 -1
- package/tests/client/css/{global-advanced-selectors.test.ripple → global-advanced-selectors.test.rsrx} +1 -1
- package/tests/client/css/{global-at-rules.test.ripple → global-at-rules.test.rsrx} +1 -1
- package/tests/client/css/{global-basic.test.ripple → global-basic.test.rsrx} +1 -1
- package/tests/client/css/{global-classes-ids.test.ripple → global-classes-ids.test.rsrx} +1 -1
- package/tests/client/css/{global-combinators.test.ripple → global-combinators.test.rsrx} +1 -1
- package/tests/client/css/{global-complex-nesting.test.ripple → global-complex-nesting.test.rsrx} +1 -1
- package/tests/client/css/{global-edge-cases.test.ripple → global-edge-cases.test.rsrx} +1 -1
- package/tests/client/css/{global-keyframes.test.ripple → global-keyframes.test.rsrx} +1 -1
- package/tests/client/css/{global-nested.test.ripple → global-nested.test.rsrx} +1 -1
- package/tests/client/css/{global-pseudo.test.ripple → global-pseudo.test.rsrx} +1 -1
- package/tests/client/css/{global-scoping.test.ripple → global-scoping.test.rsrx} +1 -1
- package/tests/client/css/{style-identifier.test.ripple → style-identifier.test.rsrx} +1 -1
- package/tests/client/{function-overload.test.ripple → function-overload.test.rsrx} +1 -1
- package/tests/client/{return.test.ripple → return.test.rsrx} +1 -1
- package/tests/client/try.test.rsrx +1702 -0
- package/tests/hydration/build-components.js +6 -4
- package/tests/hydration/compiled/client/head.js +11 -11
- package/tests/hydration/compiled/client/mixed-control-flow.js +55 -70
- package/tests/hydration/compiled/client/nested-control-flow.js +72 -88
- package/tests/hydration/compiled/client/try.js +42 -54
- package/tests/hydration/compiled/server/basic.js +491 -369
- package/tests/hydration/compiled/server/composite.js +153 -128
- package/tests/hydration/compiled/server/events.js +166 -145
- package/tests/hydration/compiled/server/for.js +821 -677
- package/tests/hydration/compiled/server/head.js +200 -165
- package/tests/hydration/compiled/server/hmr.js +62 -54
- package/tests/hydration/compiled/server/html-in-template.js +64 -55
- package/tests/hydration/compiled/server/html.js +1477 -1360
- package/tests/hydration/compiled/server/if-children.js +448 -408
- package/tests/hydration/compiled/server/if.js +204 -171
- package/tests/hydration/compiled/server/mixed-control-flow.js +237 -195
- package/tests/hydration/compiled/server/nested-control-flow.js +533 -467
- package/tests/hydration/compiled/server/portal.js +94 -107
- package/tests/hydration/compiled/server/reactivity.js +87 -64
- package/tests/hydration/compiled/server/return.js +1424 -1174
- package/tests/hydration/compiled/server/switch.js +268 -238
- package/tests/hydration/compiled/server/try.js +98 -87
- package/tests/hydration/components/{mixed-control-flow.ripple → mixed-control-flow.rsrx} +2 -2
- package/tests/hydration/components/{try.ripple → try.rsrx} +4 -2
- package/tests/hydration/mixed-control-flow.test.js +14 -0
- package/tests/hydration/nested-control-flow.test.js +50 -48
- package/tests/hydration/try.test.js +25 -0
- package/tests/server/__snapshots__/compiler.test.ripple.snap +0 -32
- package/tests/server/__snapshots__/compiler.test.rsrx.snap +95 -0
- package/tests/server/{compiler.test.ripple → compiler.test.rsrx} +0 -17
- package/tests/server/{html-nesting-validation.test.ripple → html-nesting-validation.test.rsrx} +3 -3
- package/tests/server/streaming-ssr.test.rsrx +115 -0
- package/tests/server/{style-identifier.test.ripple → style-identifier.test.rsrx} +1 -1
- package/tests/server/try.test.rsrx +503 -0
- package/tests/setup-server.js +1 -1
- package/tests/utils/compiler-compat-config.test.js +4 -4
- package/tests/utils/vite-plugin-config.test.js +1 -1
- package/tests/utils/vite-plugin-hmr.test.js +5 -5
- package/tsconfig.json +2 -0
- package/types/index.d.ts +13 -23
- package/types/server.d.ts +43 -16
- package/src/compiler/comment-utils.js +0 -91
- package/src/compiler/errors.js +0 -77
- package/src/compiler/identifier-utils.js +0 -80
- package/src/compiler/index.d.ts +0 -127
- package/src/compiler/index.js +0 -89
- package/src/compiler/phases/1-parse/index.js +0 -2964
- package/src/compiler/phases/1-parse/style.js +0 -704
- package/src/compiler/phases/2-analyze/css-analyze.js +0 -160
- package/src/compiler/phases/2-analyze/index.js +0 -2238
- package/src/compiler/phases/2-analyze/prune.js +0 -1131
- package/src/compiler/phases/2-analyze/validation.js +0 -168
- package/src/compiler/phases/3-transform/client/index.js +0 -5301
- package/src/compiler/phases/3-transform/segments.js +0 -2129
- package/src/compiler/phases/3-transform/server/index.js +0 -1899
- package/src/compiler/phases/3-transform/stylesheet.js +0 -545
- package/src/compiler/scope.js +0 -476
- package/src/compiler/source-map-utils.js +0 -358
- package/src/compiler/types/acorn.d.ts +0 -11
- package/src/compiler/types/estree-jsx.d.ts +0 -11
- package/src/compiler/types/estree.d.ts +0 -11
- package/src/compiler/types/index.d.ts +0 -1404
- package/src/compiler/types/parse.d.ts +0 -1721
- package/src/compiler/utils.js +0 -1263
- package/tests/client/_etc.test.ripple +0 -5
- package/tests/client/async-suspend.test.ripple +0 -94
- package/tests/client/try.test.ripple +0 -196
- package/tests/server/streaming-ssr.test.ripple +0 -68
- package/tests/server/try.test.ripple +0 -82
- /package/tests/client/array/{array.copy-within.test.ripple → array.copy-within.test.rsrx} +0 -0
- /package/tests/client/array/{array.derived.test.ripple → array.derived.test.rsrx} +0 -0
- /package/tests/client/array/{array.iteration.test.ripple → array.iteration.test.rsrx} +0 -0
- /package/tests/client/array/{array.mutations.test.ripple → array.mutations.test.rsrx} +0 -0
- /package/tests/client/array/{array.to-methods.test.ripple → array.to-methods.test.rsrx} +0 -0
- /package/tests/client/basic/{basic.attributes.test.ripple → basic.attributes.test.rsrx} +0 -0
- /package/tests/client/basic/{basic.collections.test.ripple → basic.collections.test.rsrx} +0 -0
- /package/tests/client/basic/{basic.components.test.ripple → basic.components.test.rsrx} +0 -0
- /package/tests/client/basic/{basic.events.test.ripple → basic.events.test.rsrx} +0 -0
- /package/tests/client/basic/{basic.get-set.test.ripple → basic.get-set.test.rsrx} +0 -0
- /package/tests/client/basic/{basic.hmr.test.ripple → basic.hmr.test.rsrx} +0 -0
- /package/tests/client/basic/{basic.reactivity.test.ripple → basic.reactivity.test.rsrx} +0 -0
- /package/tests/client/basic/{basic.rendering.test.ripple → basic.rendering.test.rsrx} +0 -0
- /package/tests/client/basic/{basic.utilities.test.ripple → basic.utilities.test.rsrx} +0 -0
- /package/tests/client/{boundaries.test.ripple → boundaries.test.rsrx} +0 -0
- /package/tests/client/compiler/{compiler.regex.test.ripple → compiler.regex.test.rsrx} +0 -0
- /package/tests/client/composite/{composite.dynamic-components.test.ripple → composite.dynamic-components.test.rsrx} +0 -0
- /package/tests/client/composite/{composite.generics.test.ripple → composite.generics.test.rsrx} +0 -0
- /package/tests/client/composite/{composite.props.test.ripple → composite.props.test.rsrx} +0 -0
- /package/tests/client/composite/{composite.reactivity.test.ripple → composite.reactivity.test.rsrx} +0 -0
- /package/tests/client/composite/{composite.render.test.ripple → composite.render.test.rsrx} +0 -0
- /package/tests/client/{computed-properties.test.ripple → computed-properties.test.rsrx} +0 -0
- /package/tests/client/{context.test.ripple → context.test.rsrx} +0 -0
- /package/tests/client/{date.test.ripple → date.test.rsrx} +0 -0
- /package/tests/client/{dynamic-elements.test.ripple → dynamic-elements.test.rsrx} +0 -0
- /package/tests/client/{events.test.ripple → events.test.rsrx} +0 -0
- /package/tests/client/{for.test.ripple → for.test.rsrx} +0 -0
- /package/tests/client/{function-overload-import.ripple → function-overload-import.rsrx} +0 -0
- /package/tests/client/{head.test.ripple → head.test.rsrx} +0 -0
- /package/tests/client/{html.test.ripple → html.test.rsrx} +0 -0
- /package/tests/client/{input-value.test.ripple → input-value.test.rsrx} +0 -0
- /package/tests/client/{lazy-destructuring.test.ripple → lazy-destructuring.test.rsrx} +0 -0
- /package/tests/client/{map.test.ripple → map.test.rsrx} +0 -0
- /package/tests/client/{media-query.test.ripple → media-query.test.rsrx} +0 -0
- /package/tests/client/{object.test.ripple → object.test.rsrx} +0 -0
- /package/tests/client/{portal.test.ripple → portal.test.rsrx} +0 -0
- /package/tests/client/{ref.test.ripple → ref.test.rsrx} +0 -0
- /package/tests/client/{set.test.ripple → set.test.rsrx} +0 -0
- /package/tests/client/{svg.test.ripple → svg.test.rsrx} +0 -0
- /package/tests/client/{switch.test.ripple → switch.test.rsrx} +0 -0
- /package/tests/client/{tsx.test.ripple → tsx.test.rsrx} +0 -0
- /package/tests/client/{typescript-generics.test.ripple → typescript-generics.test.rsrx} +0 -0
- /package/tests/client/url/{url.derived.test.ripple → url.derived.test.rsrx} +0 -0
- /package/tests/client/url/{url.parsing.test.ripple → url.parsing.test.rsrx} +0 -0
- /package/tests/client/url/{url.partial-removal.test.ripple → url.partial-removal.test.rsrx} +0 -0
- /package/tests/client/url/{url.reactivity.test.ripple → url.reactivity.test.rsrx} +0 -0
- /package/tests/client/url/{url.serialization.test.ripple → url.serialization.test.rsrx} +0 -0
- /package/tests/client/url-search-params/{url-search-params.derived.test.ripple → url-search-params.derived.test.rsrx} +0 -0
- /package/tests/client/url-search-params/{url-search-params.initialization.test.ripple → url-search-params.initialization.test.rsrx} +0 -0
- /package/tests/client/url-search-params/{url-search-params.iteration.test.ripple → url-search-params.iteration.test.rsrx} +0 -0
- /package/tests/client/url-search-params/{url-search-params.mutation.test.ripple → url-search-params.mutation.test.rsrx} +0 -0
- /package/tests/client/url-search-params/{url-search-params.retrieval.test.ripple → url-search-params.retrieval.test.rsrx} +0 -0
- /package/tests/client/url-search-params/{url-search-params.serialization.test.ripple → url-search-params.serialization.test.rsrx} +0 -0
- /package/tests/client/url-search-params/{url-search-params.tracked-url.test.ripple → url-search-params.tracked-url.test.rsrx} +0 -0
- /package/tests/hydration/components/{basic.ripple → basic.rsrx} +0 -0
- /package/tests/hydration/components/{composite.ripple → composite.rsrx} +0 -0
- /package/tests/hydration/components/{events.ripple → events.rsrx} +0 -0
- /package/tests/hydration/components/{for.ripple → for.rsrx} +0 -0
- /package/tests/hydration/components/{head.ripple → head.rsrx} +0 -0
- /package/tests/hydration/components/{hmr.ripple → hmr.rsrx} +0 -0
- /package/tests/hydration/components/{html-in-template.ripple → html-in-template.rsrx} +0 -0
- /package/tests/hydration/components/{html.ripple → html.rsrx} +0 -0
- /package/tests/hydration/components/{if-children.ripple → if-children.rsrx} +0 -0
- /package/tests/hydration/components/{if.ripple → if.rsrx} +0 -0
- /package/tests/hydration/components/{nested-control-flow.ripple → nested-control-flow.rsrx} +0 -0
- /package/tests/hydration/components/{portal.ripple → portal.rsrx} +0 -0
- /package/tests/hydration/components/{reactivity.ripple → reactivity.rsrx} +0 -0
- /package/tests/hydration/components/{return.ripple → return.rsrx} +0 -0
- /package/tests/hydration/components/{switch.ripple → switch.rsrx} +0 -0
- /package/tests/server/{await.test.ripple → await.test.rsrx} +0 -0
- /package/tests/server/{basic.attributes.test.ripple → basic.attributes.test.rsrx} +0 -0
- /package/tests/server/{basic.components.test.ripple → basic.components.test.rsrx} +0 -0
- /package/tests/server/{basic.test.ripple → basic.test.rsrx} +0 -0
- /package/tests/server/{composite.props.test.ripple → composite.props.test.rsrx} +0 -0
- /package/tests/server/{composite.test.ripple → composite.test.rsrx} +0 -0
- /package/tests/server/{context.test.ripple → context.test.rsrx} +0 -0
- /package/tests/server/{dynamic-elements.test.ripple → dynamic-elements.test.rsrx} +0 -0
- /package/tests/server/{for.test.ripple → for.test.rsrx} +0 -0
- /package/tests/server/{head.test.ripple → head.test.rsrx} +0 -0
- /package/tests/server/{if.test.ripple → if.test.rsrx} +0 -0
- /package/tests/server/{lazy-destructuring.test.ripple → lazy-destructuring.test.rsrx} +0 -0
- /package/tests/server/{return.test.ripple → return.test.rsrx} +0 -0
- /package/tests/server/{switch.test.ripple → switch.test.rsrx} +0 -0
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import { flushSync, track } from 'ripple';
|
|
2
|
-
|
|
3
|
-
describe('async suspense', () => {
|
|
4
|
-
it('hides child content during re-suspension when tracked dependency changes', async () => {
|
|
5
|
-
let resolve_fn: (() => void) | null = null;
|
|
6
|
-
|
|
7
|
-
component Child({ countTracked }: { countTracked: any }) {
|
|
8
|
-
await track(() => {
|
|
9
|
-
countTracked.value;
|
|
10
|
-
return new Promise<void>((resolve) => {
|
|
11
|
-
resolve_fn = resolve;
|
|
12
|
-
});
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
<div class="child-content">{'child content'}</div>
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
component App() {
|
|
19
|
-
let &[count, countTracked] = track(0);
|
|
20
|
-
|
|
21
|
-
try {
|
|
22
|
-
<Child {countTracked} />
|
|
23
|
-
} pending {
|
|
24
|
-
<div class="pending">{'pending...'}</div>
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
<button onClick={() => count++}>{'Increment'}</button>
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
render(App);
|
|
31
|
-
|
|
32
|
-
// Initial state: should show pending
|
|
33
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
34
|
-
flushSync();
|
|
35
|
-
expect(container.innerHTML).toContain('pending...');
|
|
36
|
-
expect(container.innerHTML).not.toContain('child content');
|
|
37
|
-
|
|
38
|
-
// Resolve the first promise
|
|
39
|
-
(resolve_fn as () => void)?.();
|
|
40
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
41
|
-
flushSync();
|
|
42
|
-
|
|
43
|
-
// After resolution: should show child content, not pending
|
|
44
|
-
expect(container.innerHTML).toContain('child content');
|
|
45
|
-
expect(container.innerHTML).not.toContain('pending...');
|
|
46
|
-
|
|
47
|
-
// Now trigger re-suspension by changing count
|
|
48
|
-
const button = container.querySelector('button');
|
|
49
|
-
button?.click();
|
|
50
|
-
flushSync();
|
|
51
|
-
|
|
52
|
-
// Wait for microtask to process
|
|
53
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
54
|
-
flushSync();
|
|
55
|
-
|
|
56
|
-
// BUG: During re-suspension, we should only see pending, not child content
|
|
57
|
-
// The child content should be hidden when the new promise is pending
|
|
58
|
-
expect(container.innerHTML).toContain('pending...');
|
|
59
|
-
expect(container.innerHTML).not.toContain('child content');
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it('shows pending UI immediately when child suspends', async () => {
|
|
63
|
-
component Child() {
|
|
64
|
-
await new Promise((resolve) => setTimeout(resolve, 50));
|
|
65
|
-
<div class="child">{'loaded'}</div>
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
component App() {
|
|
69
|
-
try {
|
|
70
|
-
<Child />
|
|
71
|
-
} pending {
|
|
72
|
-
<div class="pending">{'loading...'}</div>
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
render(App);
|
|
77
|
-
|
|
78
|
-
// Wait for microtask
|
|
79
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
80
|
-
flushSync();
|
|
81
|
-
|
|
82
|
-
// Should show pending, not child content
|
|
83
|
-
expect(container.innerHTML).toContain('loading...');
|
|
84
|
-
expect(container.innerHTML).not.toContain('loaded');
|
|
85
|
-
|
|
86
|
-
// Wait for child to resolve
|
|
87
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
88
|
-
flushSync();
|
|
89
|
-
|
|
90
|
-
// Should show child content, not pending
|
|
91
|
-
expect(container.innerHTML).toContain('loaded');
|
|
92
|
-
expect(container.innerHTML).not.toContain('loading...');
|
|
93
|
-
});
|
|
94
|
-
});
|
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
import { RippleArray, bindValue, flushSync, track } from 'ripple';
|
|
2
|
-
|
|
3
|
-
describe('try block with catch and pending', () => {
|
|
4
|
-
it('catch block works when component throws before await with pending block', async () => {
|
|
5
|
-
component App() {
|
|
6
|
-
try {
|
|
7
|
-
<ThrowingChild />
|
|
8
|
-
} pending {
|
|
9
|
-
<p>{'loading...'}</p>
|
|
10
|
-
} catch (err) {
|
|
11
|
-
<p>{'caught error'}</p>
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
component ThrowingChild() {
|
|
16
|
-
throw new Error('sync error');
|
|
17
|
-
let data = await Promise.resolve('hello');
|
|
18
|
-
<p>{data}</p>
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
render(App);
|
|
22
|
-
|
|
23
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
24
|
-
flushSync();
|
|
25
|
-
|
|
26
|
-
expect(container.innerHTML).toContain('caught error');
|
|
27
|
-
expect(container.innerHTML).not.toContain('loading...');
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
it('catch block works when component throws after await with pending block', async () => {
|
|
31
|
-
component App() {
|
|
32
|
-
try {
|
|
33
|
-
<ThrowingAfterAwait />
|
|
34
|
-
} pending {
|
|
35
|
-
<p>{'loading...'}</p>
|
|
36
|
-
} catch (err) {
|
|
37
|
-
<p>{'caught error'}</p>
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
component ThrowingAfterAwait() {
|
|
42
|
-
let data = await Promise.resolve('hello');
|
|
43
|
-
throw new Error('error after await');
|
|
44
|
-
<p>{data}</p>
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
render(App);
|
|
48
|
-
|
|
49
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
50
|
-
flushSync();
|
|
51
|
-
|
|
52
|
-
expect(container.innerHTML).toContain('caught error');
|
|
53
|
-
expect(container.innerHTML).not.toContain('loading...');
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it('catch block works with try/catch/pending when async body rejects', async () => {
|
|
57
|
-
component App() {
|
|
58
|
-
try {
|
|
59
|
-
let data = await Promise.reject(new Error('rejected'));
|
|
60
|
-
<p>{data}</p>
|
|
61
|
-
} pending {
|
|
62
|
-
<p>{'loading...'}</p>
|
|
63
|
-
} catch (err) {
|
|
64
|
-
<p>{'caught rejection'}</p>
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
render(App);
|
|
69
|
-
|
|
70
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
71
|
-
flushSync();
|
|
72
|
-
|
|
73
|
-
expect(container.innerHTML).toContain('caught rejection');
|
|
74
|
-
expect(container.innerHTML).not.toContain('loading...');
|
|
75
|
-
});
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
describe('try block', () => {
|
|
79
|
-
it(
|
|
80
|
-
'does not compile ref binds as async callbacks inside try/pending async branches',
|
|
81
|
-
async () => {
|
|
82
|
-
component App() {
|
|
83
|
-
try {
|
|
84
|
-
<Child />
|
|
85
|
-
} pending {
|
|
86
|
-
<p>{'loading...'}</p>
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
component Child() {
|
|
91
|
-
let &[value, valueTracked] = track(1);
|
|
92
|
-
await Promise.resolve(value + 1);
|
|
93
|
-
|
|
94
|
-
<input type="number" {ref bindValue(valueTracked)} />
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
render(App);
|
|
98
|
-
|
|
99
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
100
|
-
flushSync();
|
|
101
|
-
|
|
102
|
-
const input = container.querySelector('input') as HTMLInputElement | null;
|
|
103
|
-
expect(input?.value).toBe('1');
|
|
104
|
-
expect(container.innerHTML).not.toContain('loading...');
|
|
105
|
-
},
|
|
106
|
-
);
|
|
107
|
-
|
|
108
|
-
it('does not crash when async component is used inside try/pending', async () => {
|
|
109
|
-
component App() {
|
|
110
|
-
try {
|
|
111
|
-
<AsyncChild />
|
|
112
|
-
} pending {
|
|
113
|
-
<p>{'loading...'}</p>
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
component AsyncChild() {
|
|
118
|
-
let data = await Promise.resolve(['a', 'b', 'c']);
|
|
119
|
-
|
|
120
|
-
<ul>
|
|
121
|
-
for (let item of data) {
|
|
122
|
-
<li>{item}</li>
|
|
123
|
-
}
|
|
124
|
-
</ul>
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
render(App);
|
|
128
|
-
|
|
129
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
130
|
-
flushSync();
|
|
131
|
-
|
|
132
|
-
const items = container.querySelectorAll('li');
|
|
133
|
-
expect(items.length).toBe(3);
|
|
134
|
-
expect(items[0].textContent).toBe('a');
|
|
135
|
-
expect(items[1].textContent).toBe('b');
|
|
136
|
-
expect(items[2].textContent).toBe('c');
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
it(
|
|
140
|
-
'does not crash when async component with tracked state is used inside try/pending',
|
|
141
|
-
async () => {
|
|
142
|
-
component App() {
|
|
143
|
-
let query = track('');
|
|
144
|
-
|
|
145
|
-
try {
|
|
146
|
-
<FilteredList {query} />
|
|
147
|
-
} pending {
|
|
148
|
-
<p>{'loading...'}</p>
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
component FilteredList({ query }: { query: any }) {
|
|
153
|
-
let items = await Promise.resolve(['apple', 'banana', 'cherry']);
|
|
154
|
-
let list = RippleArray.from(items);
|
|
155
|
-
let &[filtered] = track(() => list.filter((item: string) => item.includes(query.value)));
|
|
156
|
-
|
|
157
|
-
<ul>
|
|
158
|
-
for (let item of filtered) {
|
|
159
|
-
<li>{item}</li>
|
|
160
|
-
}
|
|
161
|
-
</ul>
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
render(App);
|
|
165
|
-
|
|
166
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
167
|
-
flushSync();
|
|
168
|
-
|
|
169
|
-
const listItems = container.querySelectorAll('li');
|
|
170
|
-
expect(listItems.length).toBe(3);
|
|
171
|
-
},
|
|
172
|
-
);
|
|
173
|
-
|
|
174
|
-
it('if test condition does not become async within try/pending', async () => {
|
|
175
|
-
component App() {
|
|
176
|
-
try {
|
|
177
|
-
let items = await Promise.resolve(['apple', 'banana', 'cherry']);
|
|
178
|
-
|
|
179
|
-
if (items.includes('not-in-list')) {
|
|
180
|
-
<p>{'not-in-list is in the list!'}</p>
|
|
181
|
-
} else {
|
|
182
|
-
<p>{'not-in-list is not in the list.'}</p>
|
|
183
|
-
}
|
|
184
|
-
} pending {
|
|
185
|
-
<p>{'loading...'}</p>
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
render(App);
|
|
190
|
-
|
|
191
|
-
await new Promise((resolve) => setTimeout(resolve, 0));
|
|
192
|
-
flushSync();
|
|
193
|
-
|
|
194
|
-
expect(container.innerHTML).toContain('not-in-list is not in the list.');
|
|
195
|
-
});
|
|
196
|
-
});
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
import { renderToStream } from 'ripple/server';
|
|
2
|
-
|
|
3
|
-
test('renderToStream renders a simple component', async ({ expect }) => {
|
|
4
|
-
component Basic() {
|
|
5
|
-
<div>{'Hello, streaming SSR!'}</div>
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
const stream = renderToStream(Basic);
|
|
9
|
-
|
|
10
|
-
let result = '';
|
|
11
|
-
await new Promise((resolve) => {
|
|
12
|
-
stream.on('data', (chunk) => {
|
|
13
|
-
result += chunk.toString();
|
|
14
|
-
});
|
|
15
|
-
stream.on('end', resolve);
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
expect(result).toBe('<div>Hello, streaming SSR!</div>');
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
test('renderToStream handles async components', async ({ expect }) => {
|
|
22
|
-
component AsyncComponent() {
|
|
23
|
-
await new Promise((resolve) => setTimeout(resolve, 10));
|
|
24
|
-
<p>{'Async content loaded.'}</p>
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const stream = renderToStream(AsyncComponent);
|
|
28
|
-
|
|
29
|
-
let result = '';
|
|
30
|
-
await new Promise((resolve) => {
|
|
31
|
-
stream.on('data', (chunk) => {
|
|
32
|
-
result += chunk.toString();
|
|
33
|
-
});
|
|
34
|
-
stream.on('end', resolve);
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
expect(result).toBe('<p>Async content loaded.</p>');
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
test('renderToStream handles await blocks with pending state', async ({ expect }) => {
|
|
41
|
-
component AwaitComponent() {
|
|
42
|
-
let data = 'initial';
|
|
43
|
-
await new Promise((resolve) => setTimeout(() => {
|
|
44
|
-
data = 'resolved';
|
|
45
|
-
resolve('');
|
|
46
|
-
}, 20));
|
|
47
|
-
try {
|
|
48
|
-
<div>
|
|
49
|
-
{'Data: '}
|
|
50
|
-
{data}
|
|
51
|
-
</div>
|
|
52
|
-
} pending {
|
|
53
|
-
<div>{'Loading...'}</div>
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const stream = renderToStream(AwaitComponent);
|
|
58
|
-
|
|
59
|
-
let result = '';
|
|
60
|
-
await new Promise((resolve) => {
|
|
61
|
-
stream.on('data', (chunk) => {
|
|
62
|
-
result += chunk.toString();
|
|
63
|
-
});
|
|
64
|
-
stream.on('end', resolve);
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
expect(result).toBe('<!--[--><div>Loading...</div><div>Data: resolved</div><!--]-->');
|
|
68
|
-
});
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
describe('try block with catch and pending (server)', () => {
|
|
2
|
-
it('catch block works when component throws before await with pending block', async () => {
|
|
3
|
-
component ThrowingChild() {
|
|
4
|
-
throw new Error('sync error');
|
|
5
|
-
let data = await Promise.resolve('hello');
|
|
6
|
-
<p>{data}</p>
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
component App() {
|
|
10
|
-
try {
|
|
11
|
-
<ThrowingChild />
|
|
12
|
-
} pending {
|
|
13
|
-
<p>{'loading...'}</p>
|
|
14
|
-
} catch (err) {
|
|
15
|
-
<p>{'caught error'}</p>
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const { body } = await render(App);
|
|
20
|
-
expect(body).toContain('caught error');
|
|
21
|
-
expect(body).not.toContain('loading...');
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
it('catch block works when component throws after await with pending block', async () => {
|
|
25
|
-
component ThrowingAfterAwait() {
|
|
26
|
-
let data = await Promise.resolve('hello');
|
|
27
|
-
throw new Error('error after await');
|
|
28
|
-
<p>{data}</p>
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
component App() {
|
|
32
|
-
try {
|
|
33
|
-
<ThrowingAfterAwait />
|
|
34
|
-
} pending {
|
|
35
|
-
<p>{'loading...'}</p>
|
|
36
|
-
} catch (err) {
|
|
37
|
-
<p>{'caught error'}</p>
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const { body } = await render(App);
|
|
42
|
-
expect(body).toContain('caught error');
|
|
43
|
-
expect(body).not.toContain('loading...');
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
it('catch block works with try/catch/pending when async body rejects', async () => {
|
|
47
|
-
component App() {
|
|
48
|
-
try {
|
|
49
|
-
let data = await Promise.reject(new Error('rejected'));
|
|
50
|
-
<p>{data}</p>
|
|
51
|
-
} pending {
|
|
52
|
-
<p>{'loading...'}</p>
|
|
53
|
-
} catch (err) {
|
|
54
|
-
<p>{'caught rejection'}</p>
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const { body } = await render(App);
|
|
59
|
-
expect(body).toContain('caught rejection');
|
|
60
|
-
expect(body).not.toContain('loading...');
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it('removes pending content for nested try/pending blocks', async () => {
|
|
64
|
-
component App() {
|
|
65
|
-
try {
|
|
66
|
-
try {
|
|
67
|
-
let data = await Promise.resolve('resolved');
|
|
68
|
-
<p>{data}</p>
|
|
69
|
-
} pending {
|
|
70
|
-
<p>{'inner loading...'}</p>
|
|
71
|
-
}
|
|
72
|
-
} pending {
|
|
73
|
-
<p>{'outer loading...'}</p>
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const { body } = await render(App);
|
|
78
|
-
expect(body).toContain('resolved');
|
|
79
|
-
expect(body).not.toContain('outer loading...');
|
|
80
|
-
expect(body).not.toContain('inner loading...');
|
|
81
|
-
});
|
|
82
|
-
});
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/tests/client/composite/{composite.generics.test.ripple → composite.generics.test.rsrx}
RENAMED
|
File without changes
|
|
File without changes
|
/package/tests/client/composite/{composite.reactivity.test.ripple → composite.reactivity.test.rsrx}
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|