ripple 0.3.92 → 0.3.94

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 CHANGED
@@ -1,5 +1,25 @@
1
1
  # ripple
2
2
 
3
+ ## 0.3.94
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+ [[`78502e4`](https://github.com/Ripple-TS/ripple/commit/78502e46929df2165d288dbb2483f48e9254ef35)]:
9
+ - @tsrx/core@0.1.38
10
+ - @tsrx/ripple@0.1.39
11
+
12
+ ## 0.3.93
13
+
14
+ ### Patch Changes
15
+
16
+ - [`9db5a49`](https://github.com/Ripple-TS/ripple/commit/9db5a49e45c2eb3bb4f6b46c65c0aaf9016633ad)
17
+ Thanks [@leonidaz](https://github.com/leonidaz)! - Rename the `ripple/server`
18
+ helper exports to camelCase: `create_ssr_stream` is now `createStream` and
19
+ `get_css_for_hashes` is now `getCss` (returning the CSS text for the scoped
20
+ style hashes collected by `render()`). The old snake_case exports are removed;
21
+ update imports accordingly. The vite plugin consumes the new names internally.
22
+
3
23
  ## 0.3.92
4
24
 
5
25
  ### 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.92",
6
+ "version": "0.3.94",
7
7
  "type": "module",
8
8
  "module": "src/runtime/index-client.js",
9
9
  "main": "src/runtime/index-client.js",
@@ -73,8 +73,8 @@
73
73
  "clsx": "^2.1.1",
74
74
  "devalue": "^5.8.1",
75
75
  "esm-env": "^1.2.2",
76
- "@tsrx/core": "0.1.37",
77
- "@tsrx/ripple": "0.1.38"
76
+ "@tsrx/core": "0.1.38",
77
+ "@tsrx/ripple": "0.1.39"
78
78
  },
79
79
  "devDependencies": {
80
80
  "@types/estree": "^1.0.8",
@@ -23,7 +23,7 @@ export function register_component_css(hash, content) {
23
23
  * @param {Set<string>} hashes
24
24
  * @returns {string}
25
25
  */
26
- export function get_css_for_hashes(hashes) {
26
+ export function get_css_text(hashes) {
27
27
  const css_parts = [];
28
28
  for (const hash of hashes) {
29
29
  const content = css_registry.get(hash);
@@ -71,7 +71,7 @@ import {
71
71
  STREAM_HEAD_ATTR,
72
72
  STREAM_ERROR_SCRIPT_PREFIX,
73
73
  } from '../../../constants.js';
74
- import { get_css_for_hashes } from './css-registry.js';
74
+ import { get_css_text } from './css-registry.js';
75
75
  import { STREAM_RUNTIME_SCRIPT } from './stream-runtime.js';
76
76
  import { is_tsrx_element, normalize_children, tsrx_element } from '../../element.js';
77
77
  import {
@@ -672,7 +672,7 @@ export class Output {
672
672
  if (root.#shell_flushed) {
673
673
  if (!root.#sent_css.has(hash)) {
674
674
  root.#sent_css.add(hash);
675
- var css_text = get_css_for_hashes(new Set([hash]));
675
+ var css_text = get_css_text(new Set([hash]));
676
676
  if (css_text) {
677
677
  root.#streamOutput.push('<style data-ripple-ssr>' + css_text + '</style>');
678
678
  }
@@ -886,7 +886,7 @@ export class Output {
886
886
  if (fresh.size === 0) {
887
887
  return '';
888
888
  }
889
- var css_text = get_css_for_hashes(fresh);
889
+ var css_text = get_css_text(fresh);
890
890
  return css_text ? '<style data-ripple-ssr>' + css_text + '</style>' : '';
891
891
  }
892
892
 
@@ -1,6 +1,6 @@
1
1
  // SSR helpers
2
- export { create_ssr_stream, render } from '../runtime/internal/server/index.js';
3
- export { get_css_for_hashes } from '../runtime/internal/server/css-registry.js';
2
+ export { create_ssr_stream as createStream, render } from '../runtime/internal/server/index.js';
3
+ export { get_css_text as getCss } from '../runtime/internal/server/css-registry.js';
4
4
  export { executeServerFunction } from '../runtime/internal/server/rpc.js';
5
5
 
6
6
  // Re-export server runtime for components compiled for SSR
@@ -206,6 +206,44 @@ describe('head elements', () => {
206
206
  }
207
207
  });
208
208
 
209
+ it('renders an inline raw-text <script> body as script text content', () => {
210
+ function App() @{
211
+ <head>
212
+ <script>
213
+ const value = 1 < 2 ? 'a' : 'b';
214
+ window.__ripple_script_test = value;
215
+ </script>
216
+ </head>
217
+ }
218
+
219
+ const added: HTMLScriptElement[] = [];
220
+ try {
221
+ render(App);
222
+ flushSync();
223
+
224
+ const inline_scripts = Array.from(
225
+ document.head.querySelectorAll('script:not([src])'),
226
+ ) as HTMLScriptElement[];
227
+
228
+ for (const node of inline_scripts) {
229
+ if (node.textContent?.includes('__ripple_script_test')) {
230
+ added.push(node);
231
+ }
232
+ }
233
+
234
+ expect(added).toHaveLength(1);
235
+ // The body is injected verbatim, including the authored indentation, so
236
+ // assert on the statements rather than the exact whitespace.
237
+ const body = added[0].textContent ?? '';
238
+ expect(body).toContain('const value = 1 < 2 ? \'a\' : \'b\';');
239
+ expect(body).toContain('window.__ripple_script_test = value;');
240
+ } finally {
241
+ for (const node of added) {
242
+ node.remove();
243
+ }
244
+ }
245
+ });
246
+
209
247
  it('renders title with conditional content', () => {
210
248
  function App() @{
211
249
  let &[showPrefix] = track(true);
@@ -113,6 +113,23 @@ describe('head elements', () => {
113
113
  expect(srcs).toEqual(['/a.js', '/b.js']);
114
114
  });
115
115
 
116
+ it('renders an inline raw-text <script> body verbatim', async () => {
117
+ function App() @{
118
+ <head>
119
+ <script>
120
+ const value = 1 < 2 ? 'a' : 'b';
121
+ </script>
122
+ </head>
123
+ }
124
+
125
+ const { head } = await render(App);
126
+
127
+ // The body is emitted verbatim (unescaped), including the authored
128
+ // indentation, so match the statement inside the tags rather than the
129
+ // exact whitespace.
130
+ expect(head).toMatch(/<script>[\s\S]*const value = 1 < 2 \? 'a' : 'b';[\s\S]*<\/script>/);
131
+ });
132
+
116
133
  it('renders title with conditional content', async () => {
117
134
  function App() @{
118
135
  let &[showPrefix] = track(true);
@@ -1,4 +1,4 @@
1
- import { create_ssr_stream } from 'ripple/server';
1
+ import { createStream } from 'ripple/server';
2
2
  import { trackAsync } from 'ripple';
3
3
 
4
4
  interface Deferred<T> {
@@ -98,13 +98,13 @@ function normalize(html: string): string {
98
98
  ).replace(/<style data-ripple-ssr>[\s\S]*?<\/style>/g, '');
99
99
  }
100
100
 
101
- describe('create_ssr_stream', () => {
101
+ describe('createStream', () => {
102
102
  it('renders SSR HTML into the injected sink and exposes a web stream', async () => {
103
103
  function App() @{
104
104
  <div>{'Hello, streaming SSR!'}</div>
105
105
  }
106
106
 
107
- const { stream, sink } = create_ssr_stream();
107
+ const { stream, sink } = createStream();
108
108
 
109
109
  expect(stream).toBeInstanceOf(ReadableStream);
110
110
  await render(App, { stream: sink });
@@ -118,7 +118,7 @@ describe('create_ssr_stream', () => {
118
118
  <p>{'stream closed'}</p>
119
119
  }
120
120
 
121
- const { stream, sink } = create_ssr_stream();
121
+ const { stream, sink } = createStream();
122
122
  const reader = stream.getReader();
123
123
  const decoder = new TextDecoder();
124
124
  let html = '';
package/types/server.d.ts CHANGED
@@ -74,7 +74,13 @@ export interface RenderOptions extends BaseRenderOptions {
74
74
  stream?: undefined;
75
75
  }
76
76
 
77
- export declare function create_ssr_stream(): Stream;
77
+ export declare function createStream(): Stream;
78
+
79
+ /**
80
+ * Returns the CSS text for a set of scoped style hashes collected by
81
+ * `render()` — emit it in a `<style data-ripple-ssr>` tag.
82
+ */
83
+ export declare function getCss(css: Set<string>): string;
78
84
 
79
85
  export declare function render(
80
86
  component: Component,