solid-js 1.4.0-beta.0 → 1.4.0-beta.3

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/dist/dev.cjs CHANGED
@@ -263,6 +263,7 @@ function createResource(source, fetcher, options) {
263
263
  id = null,
264
264
  loadedUnderTransition = false,
265
265
  scheduled = false,
266
+ resolved = ("initialValue" in options),
266
267
  dynamic = typeof source === "function" && createMemo(source);
267
268
  if (sharedConfig.context) {
268
269
  id = `${sharedConfig.context.id}${sharedConfig.context.count++}`;
@@ -271,9 +272,10 @@ function createResource(source, fetcher, options) {
271
272
  function loadEnd(p, v, e, key) {
272
273
  if (pr === p) {
273
274
  pr = null;
274
- if (initP && p === initP && options.onHydrated) options.onHydrated(key, {
275
+ resolved = true;
276
+ if (initP && (p === initP || v === initP) && options.onHydrated) queueMicrotask(() => options.onHydrated(key, {
275
277
  value: v
276
- });
278
+ }));
277
279
  initP = null;
278
280
  setError(err = e);
279
281
  if (Transition && p && loadedUnderTransition) {
@@ -357,6 +359,7 @@ function createResource(source, fetcher, options) {
357
359
  },
358
360
  latest: {
359
361
  get() {
362
+ if (!resolved) return read();
360
363
  if (err) throw err;
361
364
  return value();
362
365
  }
@@ -1229,12 +1232,12 @@ function createComponent(Comp, props) {
1229
1232
  if (sharedConfig.context) {
1230
1233
  const c = sharedConfig.context;
1231
1234
  setHydrateContext(nextHydrateContext());
1232
- const r = devComponent(Comp, props) ;
1235
+ const r = devComponent(Comp, props || {}) ;
1233
1236
  setHydrateContext(c);
1234
1237
  return r;
1235
1238
  }
1236
1239
  }
1237
- return devComponent(Comp, props);
1240
+ return devComponent(Comp, props || {});
1238
1241
  }
1239
1242
  function trueFn() {
1240
1243
  return true;
@@ -1265,7 +1268,7 @@ const propTraps = {
1265
1268
  }
1266
1269
  };
1267
1270
  function resolveSource(s) {
1268
- return typeof s === "function" ? s() : s;
1271
+ return (s = typeof s === "function" ? s() : s) == null ? {} : s;
1269
1272
  }
1270
1273
  function mergeProps(...sources) {
1271
1274
  return new Proxy({
package/dist/dev.js CHANGED
@@ -259,6 +259,7 @@ function createResource(source, fetcher, options) {
259
259
  id = null,
260
260
  loadedUnderTransition = false,
261
261
  scheduled = false,
262
+ resolved = ("initialValue" in options),
262
263
  dynamic = typeof source === "function" && createMemo(source);
263
264
  if (sharedConfig.context) {
264
265
  id = `${sharedConfig.context.id}${sharedConfig.context.count++}`;
@@ -267,9 +268,10 @@ function createResource(source, fetcher, options) {
267
268
  function loadEnd(p, v, e, key) {
268
269
  if (pr === p) {
269
270
  pr = null;
270
- if (initP && p === initP && options.onHydrated) options.onHydrated(key, {
271
+ resolved = true;
272
+ if (initP && (p === initP || v === initP) && options.onHydrated) queueMicrotask(() => options.onHydrated(key, {
271
273
  value: v
272
- });
274
+ }));
273
275
  initP = null;
274
276
  setError(err = e);
275
277
  if (Transition && p && loadedUnderTransition) {
@@ -353,6 +355,7 @@ function createResource(source, fetcher, options) {
353
355
  },
354
356
  latest: {
355
357
  get() {
358
+ if (!resolved) return read();
356
359
  if (err) throw err;
357
360
  return value();
358
361
  }
@@ -1225,12 +1228,12 @@ function createComponent(Comp, props) {
1225
1228
  if (sharedConfig.context) {
1226
1229
  const c = sharedConfig.context;
1227
1230
  setHydrateContext(nextHydrateContext());
1228
- const r = devComponent(Comp, props) ;
1231
+ const r = devComponent(Comp, props || {}) ;
1229
1232
  setHydrateContext(c);
1230
1233
  return r;
1231
1234
  }
1232
1235
  }
1233
- return devComponent(Comp, props);
1236
+ return devComponent(Comp, props || {});
1234
1237
  }
1235
1238
  function trueFn() {
1236
1239
  return true;
@@ -1261,7 +1264,7 @@ const propTraps = {
1261
1264
  }
1262
1265
  };
1263
1266
  function resolveSource(s) {
1264
- return typeof s === "function" ? s() : s;
1267
+ return (s = typeof s === "function" ? s() : s) == null ? {} : s;
1265
1268
  }
1266
1269
  function mergeProps(...sources) {
1267
1270
  return new Proxy({
package/dist/server.cjs CHANGED
@@ -249,11 +249,11 @@ function createComponent(Comp, props) {
249
249
  if (sharedConfig.context && !sharedConfig.context.noHydrate) {
250
250
  const c = sharedConfig.context;
251
251
  setHydrateContext(nextHydrateContext());
252
- const r = Comp(props);
252
+ const r = Comp(props || {});
253
253
  setHydrateContext(c);
254
254
  return r;
255
255
  }
256
- return Comp(props);
256
+ return Comp(props || {});
257
257
  }
258
258
  function mergeProps(...sources) {
259
259
  const target = {};
@@ -372,6 +372,11 @@ function createResource(source, fetcher, options = {}) {
372
372
  };
373
373
  read.loading = false;
374
374
  read.error = undefined;
375
+ Object.defineProperty(read, "latest", {
376
+ get() {
377
+ return read();
378
+ }
379
+ });
375
380
  function load() {
376
381
  const ctx = sharedConfig.context;
377
382
  if (!ctx.async) return read.loading = !!(typeof source === "function" ? source() : source);
@@ -395,7 +400,7 @@ function createResource(source, fetcher, options = {}) {
395
400
  }
396
401
  if (p && "then" in p) {
397
402
  read.loading = true;
398
- if (ctx.writeResource) ctx.writeResource(id, p);
403
+ if (ctx.writeResource) ctx.writeResource(id, p, undefined, options.deferStream);
399
404
  return p.then(res => {
400
405
  read.loading = false;
401
406
  ctx.resources[id].data = res;
package/dist/server.js CHANGED
@@ -245,11 +245,11 @@ function createComponent(Comp, props) {
245
245
  if (sharedConfig.context && !sharedConfig.context.noHydrate) {
246
246
  const c = sharedConfig.context;
247
247
  setHydrateContext(nextHydrateContext());
248
- const r = Comp(props);
248
+ const r = Comp(props || {});
249
249
  setHydrateContext(c);
250
250
  return r;
251
251
  }
252
- return Comp(props);
252
+ return Comp(props || {});
253
253
  }
254
254
  function mergeProps(...sources) {
255
255
  const target = {};
@@ -368,6 +368,11 @@ function createResource(source, fetcher, options = {}) {
368
368
  };
369
369
  read.loading = false;
370
370
  read.error = undefined;
371
+ Object.defineProperty(read, "latest", {
372
+ get() {
373
+ return read();
374
+ }
375
+ });
371
376
  function load() {
372
377
  const ctx = sharedConfig.context;
373
378
  if (!ctx.async) return read.loading = !!(typeof source === "function" ? source() : source);
@@ -391,7 +396,7 @@ function createResource(source, fetcher, options = {}) {
391
396
  }
392
397
  if (p && "then" in p) {
393
398
  read.loading = true;
394
- if (ctx.writeResource) ctx.writeResource(id, p);
399
+ if (ctx.writeResource) ctx.writeResource(id, p, undefined, options.deferStream);
395
400
  return p.then(res => {
396
401
  read.loading = false;
397
402
  ctx.resources[id].data = res;
package/dist/solid.cjs CHANGED
@@ -260,6 +260,7 @@ function createResource(source, fetcher, options) {
260
260
  id = null,
261
261
  loadedUnderTransition = false,
262
262
  scheduled = false,
263
+ resolved = ("initialValue" in options),
263
264
  dynamic = typeof source === "function" && createMemo(source);
264
265
  if (sharedConfig.context) {
265
266
  id = `${sharedConfig.context.id}${sharedConfig.context.count++}`;
@@ -268,9 +269,10 @@ function createResource(source, fetcher, options) {
268
269
  function loadEnd(p, v, e, key) {
269
270
  if (pr === p) {
270
271
  pr = null;
271
- if (initP && p === initP && options.onHydrated) options.onHydrated(key, {
272
+ resolved = true;
273
+ if (initP && (p === initP || v === initP) && options.onHydrated) queueMicrotask(() => options.onHydrated(key, {
272
274
  value: v
273
- });
275
+ }));
274
276
  initP = null;
275
277
  setError(err = e);
276
278
  if (Transition && p && loadedUnderTransition) {
@@ -354,6 +356,7 @@ function createResource(source, fetcher, options) {
354
356
  },
355
357
  latest: {
356
358
  get() {
359
+ if (!resolved) return read();
357
360
  if (err) throw err;
358
361
  return value();
359
362
  }
@@ -1148,12 +1151,12 @@ function createComponent(Comp, props) {
1148
1151
  if (sharedConfig.context) {
1149
1152
  const c = sharedConfig.context;
1150
1153
  setHydrateContext(nextHydrateContext());
1151
- const r = untrack(() => Comp(props));
1154
+ const r = untrack(() => Comp(props || {}));
1152
1155
  setHydrateContext(c);
1153
1156
  return r;
1154
1157
  }
1155
1158
  }
1156
- return untrack(() => Comp(props));
1159
+ return untrack(() => Comp(props || {}));
1157
1160
  }
1158
1161
  function trueFn() {
1159
1162
  return true;
@@ -1184,7 +1187,7 @@ const propTraps = {
1184
1187
  }
1185
1188
  };
1186
1189
  function resolveSource(s) {
1187
- return typeof s === "function" ? s() : s;
1190
+ return (s = typeof s === "function" ? s() : s) == null ? {} : s;
1188
1191
  }
1189
1192
  function mergeProps(...sources) {
1190
1193
  return new Proxy({
package/dist/solid.js CHANGED
@@ -256,6 +256,7 @@ function createResource(source, fetcher, options) {
256
256
  id = null,
257
257
  loadedUnderTransition = false,
258
258
  scheduled = false,
259
+ resolved = ("initialValue" in options),
259
260
  dynamic = typeof source === "function" && createMemo(source);
260
261
  if (sharedConfig.context) {
261
262
  id = `${sharedConfig.context.id}${sharedConfig.context.count++}`;
@@ -264,9 +265,10 @@ function createResource(source, fetcher, options) {
264
265
  function loadEnd(p, v, e, key) {
265
266
  if (pr === p) {
266
267
  pr = null;
267
- if (initP && p === initP && options.onHydrated) options.onHydrated(key, {
268
+ resolved = true;
269
+ if (initP && (p === initP || v === initP) && options.onHydrated) queueMicrotask(() => options.onHydrated(key, {
268
270
  value: v
269
- });
271
+ }));
270
272
  initP = null;
271
273
  setError(err = e);
272
274
  if (Transition && p && loadedUnderTransition) {
@@ -350,6 +352,7 @@ function createResource(source, fetcher, options) {
350
352
  },
351
353
  latest: {
352
354
  get() {
355
+ if (!resolved) return read();
353
356
  if (err) throw err;
354
357
  return value();
355
358
  }
@@ -1144,12 +1147,12 @@ function createComponent(Comp, props) {
1144
1147
  if (sharedConfig.context) {
1145
1148
  const c = sharedConfig.context;
1146
1149
  setHydrateContext(nextHydrateContext());
1147
- const r = untrack(() => Comp(props));
1150
+ const r = untrack(() => Comp(props || {}));
1148
1151
  setHydrateContext(c);
1149
1152
  return r;
1150
1153
  }
1151
1154
  }
1152
- return untrack(() => Comp(props));
1155
+ return untrack(() => Comp(props || {}));
1153
1156
  }
1154
1157
  function trueFn() {
1155
1158
  return true;
@@ -1180,7 +1183,7 @@ const propTraps = {
1180
1183
  }
1181
1184
  };
1182
1185
  function resolveSource(s) {
1183
- return typeof s === "function" ? s() : s;
1186
+ return (s = typeof s === "function" ? s() : s) == null ? {} : s;
1184
1187
  }
1185
1188
  function mergeProps(...sources) {
1186
1189
  return new Proxy({
@@ -0,0 +1,27 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var h = require('solid-js/h');
6
+
7
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
8
+
9
+ var h__default = /*#__PURE__*/_interopDefaultLegacy(h);
10
+
11
+ function Fragment(props) {
12
+ return props.children;
13
+ }
14
+
15
+ Object.defineProperty(exports, 'jsx', {
16
+ enumerable: true,
17
+ get: function () { return h__default["default"]; }
18
+ });
19
+ Object.defineProperty(exports, 'jsxDEV', {
20
+ enumerable: true,
21
+ get: function () { return h__default["default"]; }
22
+ });
23
+ Object.defineProperty(exports, 'jsxs', {
24
+ enumerable: true,
25
+ get: function () { return h__default["default"]; }
26
+ });
27
+ exports.Fragment = Fragment;
@@ -0,0 +1,7 @@
1
+ export { default as jsx, default as jsxDEV, default as jsxs } from 'solid-js/h';
2
+
3
+ function Fragment(props) {
4
+ return props.children;
5
+ }
6
+
7
+ export { Fragment };
@@ -0,0 +1,8 @@
1
+ {
2
+ "name": "solid-js/jsx-runtime",
3
+ "main": "./dist/jsx.cjs",
4
+ "module": "./dist/jsx.js",
5
+ "types": "./types/index.d.ts",
6
+ "type": "module",
7
+ "sideEffects": false
8
+ }
@@ -0,0 +1,7 @@
1
+ import h from "solid-js/h";
2
+ export type { JSX } from "solid-js";
3
+ import type { JSX } from "solid-js";
4
+ declare function Fragment(props: {
5
+ children: JSX.Element;
6
+ }): JSX.Element;
7
+ export { h as jsx, h as jsxs, h as jsxDEV, Fragment };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "solid-js",
3
3
  "description": "A declarative JavaScript library for building user interfaces.",
4
- "version": "1.4.0-beta.0",
4
+ "version": "1.4.0-beta.3",
5
5
  "author": "Ryan Carniato",
6
6
  "license": "MIT",
7
7
  "homepage": "https://solidjs.com",
@@ -32,7 +32,8 @@
32
32
  "universal/dist",
33
33
  "universal/types",
34
34
  "types",
35
- "jsx-runtime.d.ts"
35
+ "jsx-runtime/dist",
36
+ "jsx-runtime/types"
36
37
  ],
37
38
  "exports": {
38
39
  ".": {
@@ -116,7 +117,11 @@
116
117
  "import": "./html/dist/html.js",
117
118
  "require": "./html/dist/html.cjs"
118
119
  },
119
- "./html/dist/*": "./html/dist/*"
120
+ "./html/dist/*": "./html/dist/*",
121
+ "./jsx-runtime": {
122
+ "import": "./html/dist/jsx.js",
123
+ "require": "./html/dist/jsx.cjs"
124
+ }
120
125
  },
121
126
  "scripts": {
122
127
  "prebuild": "npm run clean",
@@ -129,6 +134,7 @@
129
134
  "build:types-web": "tsc --project ./web/tsconfig.build.json && tsconfig-replace-paths --project ./web/tsconfig.types.json",
130
135
  "build:types-html": "tsc --project ./html/tsconfig.json",
131
136
  "build:types-h": "tsc --project ./h/tsconfig.json",
137
+ "build:types-jsx": "tsc --project ./jsx-runtime/tsconfig.json",
132
138
  "build:types-universal": "tsc --project ./universal/tsconfig.json",
133
139
  "bench": "node --allow-natives-syntax bench/bench.cjs",
134
140
  "test": "jest && npm run test:types",
@@ -144,5 +150,5 @@
144
150
  "compiler",
145
151
  "performance"
146
152
  ],
147
- "gitHead": "c47bee46d775574c4eebd94ea207f4e679f08d60"
153
+ "gitHead": "0919e999b84569a9d1d3b5cf4948f34952960784"
148
154
  }
@@ -134,6 +134,9 @@ function mergeStoreNode(state, value) {
134
134
  }
135
135
  }
136
136
  function updateArray(current, next) {
137
+ if (typeof next === "function") next = next(current);
138
+ next = unwrap(next);
139
+ if (current === next) return;
137
140
  let i = 0,
138
141
  len = next.length;
139
142
  for (; i < len; i++) {
@@ -200,7 +203,7 @@ function createStore(store, options) {
200
203
  }
201
204
  function setStore(...args) {
202
205
  solidJs.batch(() => {
203
- isArray && args.length === 1 ? updateArray(unwrappedStore, unwrap(args[0])) : updatePath(unwrappedStore, args);
206
+ isArray && args.length === 1 ? updateArray(unwrappedStore, args[0]) : updatePath(unwrappedStore, args);
204
207
  });
205
208
  }
206
209
  return [wrappedStore, setStore];
@@ -216,8 +219,8 @@ const proxyTraps = {
216
219
  if (solidJs.getListener() && (typeof value !== "function" || target.hasOwnProperty(property))) {
217
220
  const nodes = getDataNodes(target);
218
221
  (nodes[property] || (nodes[property] = createDataNode()))();
219
- } else if (value != null && value === Array.prototype[property]) {
220
- return (...args) => solidJs.batch(() => Array.prototype[property].apply(target, args));
222
+ } else if (value != null && typeof value === "function" && value === Array.prototype[property]) {
223
+ return (...args) => solidJs.batch(() => Array.prototype[property].apply(receiver, args));
221
224
  }
222
225
  return isWrappable(value) ? wrap(value, target[$NAME] && `${target[$NAME]}:${property.toString()}`) : value;
223
226
  },
@@ -274,6 +277,9 @@ function createMutable(state, options) {
274
277
  }
275
278
  return wrappedStore;
276
279
  }
280
+ function modifyMutable(state, modifier) {
281
+ solidJs.batch(() => modifier(unwrap(state)));
282
+ }
277
283
 
278
284
  function applyState(target, parent, property, merge, key) {
279
285
  const previous = parent[property];
@@ -382,6 +388,7 @@ function produce(fn) {
382
388
  exports.$RAW = $RAW;
383
389
  exports.createMutable = createMutable;
384
390
  exports.createStore = createStore;
391
+ exports.modifyMutable = modifyMutable;
385
392
  exports.produce = produce;
386
393
  exports.reconcile = reconcile;
387
394
  exports.unwrap = unwrap;
package/store/dist/dev.js CHANGED
@@ -130,6 +130,9 @@ function mergeStoreNode(state, value) {
130
130
  }
131
131
  }
132
132
  function updateArray(current, next) {
133
+ if (typeof next === "function") next = next(current);
134
+ next = unwrap(next);
135
+ if (current === next) return;
133
136
  let i = 0,
134
137
  len = next.length;
135
138
  for (; i < len; i++) {
@@ -196,7 +199,7 @@ function createStore(store, options) {
196
199
  }
197
200
  function setStore(...args) {
198
201
  batch(() => {
199
- isArray && args.length === 1 ? updateArray(unwrappedStore, unwrap(args[0])) : updatePath(unwrappedStore, args);
202
+ isArray && args.length === 1 ? updateArray(unwrappedStore, args[0]) : updatePath(unwrappedStore, args);
200
203
  });
201
204
  }
202
205
  return [wrappedStore, setStore];
@@ -212,8 +215,8 @@ const proxyTraps = {
212
215
  if (getListener() && (typeof value !== "function" || target.hasOwnProperty(property))) {
213
216
  const nodes = getDataNodes(target);
214
217
  (nodes[property] || (nodes[property] = createDataNode()))();
215
- } else if (value != null && value === Array.prototype[property]) {
216
- return (...args) => batch(() => Array.prototype[property].apply(target, args));
218
+ } else if (value != null && typeof value === "function" && value === Array.prototype[property]) {
219
+ return (...args) => batch(() => Array.prototype[property].apply(receiver, args));
217
220
  }
218
221
  return isWrappable(value) ? wrap(value, target[$NAME] && `${target[$NAME]}:${property.toString()}`) : value;
219
222
  },
@@ -270,6 +273,9 @@ function createMutable(state, options) {
270
273
  }
271
274
  return wrappedStore;
272
275
  }
276
+ function modifyMutable(state, modifier) {
277
+ batch(() => modifier(unwrap(state)));
278
+ }
273
279
 
274
280
  function applyState(target, parent, property, merge, key) {
275
281
  const previous = parent[property];
@@ -375,4 +381,4 @@ function produce(fn) {
375
381
  };
376
382
  }
377
383
 
378
- export { $RAW, createMutable, createStore, produce, reconcile, unwrap };
384
+ export { $RAW, createMutable, createStore, modifyMutable, produce, reconcile, unwrap };
@@ -129,6 +129,9 @@ function mergeStoreNode(state, value) {
129
129
  }
130
130
  }
131
131
  function updateArray(current, next) {
132
+ if (typeof next === "function") next = next(current);
133
+ next = unwrap(next);
134
+ if (current === next) return;
132
135
  let i = 0,
133
136
  len = next.length;
134
137
  for (; i < len; i++) {
@@ -188,7 +191,7 @@ function createStore(store, options) {
188
191
  const wrappedStore = wrap$1(unwrappedStore);
189
192
  function setStore(...args) {
190
193
  solidJs.batch(() => {
191
- isArray && args.length === 1 ? updateArray(unwrappedStore, unwrap(args[0])) : updatePath(unwrappedStore, args);
194
+ isArray && args.length === 1 ? updateArray(unwrappedStore, args[0]) : updatePath(unwrappedStore, args);
192
195
  });
193
196
  }
194
197
  return [wrappedStore, setStore];
@@ -204,8 +207,8 @@ const proxyTraps = {
204
207
  if (solidJs.getListener() && (typeof value !== "function" || target.hasOwnProperty(property))) {
205
208
  const nodes = getDataNodes(target);
206
209
  (nodes[property] || (nodes[property] = createDataNode()))();
207
- } else if (value != null && value === Array.prototype[property]) {
208
- return (...args) => solidJs.batch(() => Array.prototype[property].apply(target, args));
210
+ } else if (value != null && typeof value === "function" && value === Array.prototype[property]) {
211
+ return (...args) => solidJs.batch(() => Array.prototype[property].apply(receiver, args));
209
212
  }
210
213
  return isWrappable(value) ? wrap(value) : value;
211
214
  },
@@ -252,6 +255,9 @@ function createMutable(state, options) {
252
255
  const wrappedStore = wrap(unwrappedStore);
253
256
  return wrappedStore;
254
257
  }
258
+ function modifyMutable(state, modifier) {
259
+ solidJs.batch(() => modifier(unwrap(state)));
260
+ }
255
261
 
256
262
  function applyState(target, parent, property, merge, key) {
257
263
  const previous = parent[property];
@@ -360,6 +366,7 @@ function produce(fn) {
360
366
  exports.$RAW = $RAW;
361
367
  exports.createMutable = createMutable;
362
368
  exports.createStore = createStore;
369
+ exports.modifyMutable = modifyMutable;
363
370
  exports.produce = produce;
364
371
  exports.reconcile = reconcile;
365
372
  exports.unwrap = unwrap;
@@ -125,6 +125,9 @@ function mergeStoreNode(state, value) {
125
125
  }
126
126
  }
127
127
  function updateArray(current, next) {
128
+ if (typeof next === "function") next = next(current);
129
+ next = unwrap(next);
130
+ if (current === next) return;
128
131
  let i = 0,
129
132
  len = next.length;
130
133
  for (; i < len; i++) {
@@ -184,7 +187,7 @@ function createStore(store, options) {
184
187
  const wrappedStore = wrap$1(unwrappedStore);
185
188
  function setStore(...args) {
186
189
  batch(() => {
187
- isArray && args.length === 1 ? updateArray(unwrappedStore, unwrap(args[0])) : updatePath(unwrappedStore, args);
190
+ isArray && args.length === 1 ? updateArray(unwrappedStore, args[0]) : updatePath(unwrappedStore, args);
188
191
  });
189
192
  }
190
193
  return [wrappedStore, setStore];
@@ -200,8 +203,8 @@ const proxyTraps = {
200
203
  if (getListener() && (typeof value !== "function" || target.hasOwnProperty(property))) {
201
204
  const nodes = getDataNodes(target);
202
205
  (nodes[property] || (nodes[property] = createDataNode()))();
203
- } else if (value != null && value === Array.prototype[property]) {
204
- return (...args) => batch(() => Array.prototype[property].apply(target, args));
206
+ } else if (value != null && typeof value === "function" && value === Array.prototype[property]) {
207
+ return (...args) => batch(() => Array.prototype[property].apply(receiver, args));
205
208
  }
206
209
  return isWrappable(value) ? wrap(value) : value;
207
210
  },
@@ -248,6 +251,9 @@ function createMutable(state, options) {
248
251
  const wrappedStore = wrap(unwrappedStore);
249
252
  return wrappedStore;
250
253
  }
254
+ function modifyMutable(state, modifier) {
255
+ batch(() => modifier(unwrap(state)));
256
+ }
251
257
 
252
258
  function applyState(target, parent, property, merge, key) {
253
259
  const previous = parent[property];
@@ -353,4 +359,4 @@ function produce(fn) {
353
359
  };
354
360
  }
355
361
 
356
- export { $RAW, createMutable, createStore, produce, reconcile, unwrap };
362
+ export { $RAW, createMutable, createStore, modifyMutable, produce, reconcile, unwrap };
@@ -2,3 +2,4 @@ import { StoreNode } from "./store";
2
2
  export declare function createMutable<T extends StoreNode>(state: T, options?: {
3
3
  name?: string;
4
4
  }): T;
5
+ export declare function modifyMutable<T>(state: T, modifier: (state: T) => T): void;
@@ -1,5 +1,6 @@
1
1
  import { requestCallback } from "./scheduler";
2
2
  import type { JSX } from "../jsx";
3
+ import type { FlowComponent } from "../render";
3
4
  export declare const equalFn: <T>(a: T, b: T) => boolean;
4
5
  export declare const $PROXY: unique symbol;
5
6
  export declare const $TRACK: unique symbol;
@@ -123,8 +124,8 @@ export declare type EffectFunction<Prev, Next extends Prev = Prev> = (v: Prev) =
123
124
  *
124
125
  * @description https://www.solidjs.com/docs/latest/api#createcomputed
125
126
  */
127
+ export declare function createComputed<Next>(fn: EffectFunction<undefined | NoInfer<Next>, Next>): void;
126
128
  export declare function createComputed<Next, Init = Next>(fn: EffectFunction<Init | Next, Next>, value: Init, options?: EffectOptions): void;
127
- export declare function createComputed<Next, Init = undefined>(..._: undefined extends Init ? [fn: EffectFunction<Init | Next, Next>, value?: Init, options?: EffectOptions] : [fn: EffectFunction<Init | Next, Next>, value: Init, options?: EffectOptions]): void;
128
129
  /**
129
130
  * Creates a reactive computation that runs during the render phase as DOM elements are created and updated but not necessarily connected
130
131
  * ```typescript
@@ -140,8 +141,8 @@ export declare function createComputed<Next, Init = undefined>(..._: undefined e
140
141
  *
141
142
  * @description https://www.solidjs.com/docs/latest/api#createrendereffect
142
143
  */
144
+ export declare function createRenderEffect<Next>(fn: EffectFunction<undefined | NoInfer<Next>, Next>): void;
143
145
  export declare function createRenderEffect<Next, Init = Next>(fn: EffectFunction<Init | Next, Next>, value: Init, options?: EffectOptions): void;
144
- export declare function createRenderEffect<Next, Init = undefined>(..._: undefined extends Init ? [fn: EffectFunction<Init | Next, Next>, value?: Init, options?: EffectOptions] : [fn: EffectFunction<Init | Next, Next>, value: Init, options?: EffectOptions]): void;
145
146
  /**
146
147
  * Creates a reactive computation that runs after the render phase
147
148
  * ```typescript
@@ -157,8 +158,8 @@ export declare function createRenderEffect<Next, Init = undefined>(..._: undefin
157
158
  *
158
159
  * @description https://www.solidjs.com/docs/latest/api#createeffect
159
160
  */
161
+ export declare function createEffect<Next>(fn: EffectFunction<undefined | NoInfer<Next>, Next>): void;
160
162
  export declare function createEffect<Next, Init = Next>(fn: EffectFunction<Init | Next, Next>, value: Init, options?: EffectOptions): void;
161
- export declare function createEffect<Next, Init = undefined>(..._: undefined extends Init ? [fn: EffectFunction<Init | Next, Next>, value?: Init, options?: EffectOptions] : [fn: EffectFunction<Init | Next, Next>, value: Init, options?: EffectOptions]): void;
162
163
  /**
163
164
  * Creates a reactive computation that runs after the render phase with flexible tracking
164
165
  * ```typescript
@@ -194,8 +195,8 @@ export interface MemoOptions<T> extends EffectOptions {
194
195
  *
195
196
  * @description https://www.solidjs.com/docs/latest/api#creatememo
196
197
  */
197
- export declare function createMemo<Next extends _Next, Init = Next, _Next = Next>(fn: EffectFunction<Init | _Next, Next>, value: Init, options?: MemoOptions<Next>): Accessor<Next>;
198
- export declare function createMemo<Next extends _Next, Init = undefined, _Next = Next>(..._: undefined extends Init ? [fn: EffectFunction<Init | _Next, Next>, value?: Init, options?: MemoOptions<Next>] : [fn: EffectFunction<Init | _Next, Next>, value: Init, options?: MemoOptions<Next>]): Accessor<Next>;
198
+ export declare function createMemo<Next extends Prev, Prev = Next>(fn: EffectFunction<undefined | NoInfer<Prev>, Next>): Accessor<Next>;
199
+ export declare function createMemo<Next extends Prev, Init = Next, Prev = Next>(fn: EffectFunction<Init | Prev, Next>, value: Init, options?: MemoOptions<Next>): Accessor<Next>;
199
200
  export interface Resource<T> extends Accessor<T> {
200
201
  loading: boolean;
201
202
  error: any;
@@ -215,10 +216,12 @@ export declare type ResourceFetcherInfo<T> = {
215
216
  export declare type ResourceOptions<T> = undefined extends T ? {
216
217
  initialValue?: T;
217
218
  name?: string;
219
+ deferStream?: boolean;
218
220
  onHydrated?: <S, T>(k: S, info: ResourceFetcherInfo<T>) => void;
219
221
  } : {
220
222
  initialValue: T;
221
223
  name?: string;
224
+ deferStream?: boolean;
222
225
  onHydrated?: <S, T>(k: S, info: ResourceFetcherInfo<T>) => void;
223
226
  };
224
227
  /**
@@ -401,10 +404,9 @@ interface GraphRecord {
401
404
  [k: string]: GraphRecord | unknown;
402
405
  }
403
406
  export declare function serializeGraph(owner?: Owner | null): GraphRecord;
404
- export declare type ContextProviderComponent<T> = (props: {
407
+ export declare type ContextProviderComponent<T> = FlowComponent<{
405
408
  value: T;
406
- children: any;
407
- }) => any;
409
+ }>;
408
410
  export interface Context<T> {
409
411
  id: symbol;
410
412
  Provider: ContextProviderComponent<T>;
@@ -415,7 +417,7 @@ export interface Context<T> {
415
417
  * ```typescript
416
418
  * interface Context<T> {
417
419
  * id: symbol;
418
- * Provider: (props: { value: T; children: any }) => any;
420
+ * Provider: FlowComponent<{ value: T }>;
419
421
  * defaultValue: T;
420
422
  * }
421
423
  * export function createContext<T>(defaultValue?: T): Context<T | undefined>;
@@ -1,9 +1,56 @@
1
1
  import type { JSX } from "../jsx";
2
2
  export declare function enableHydration(): void;
3
- export declare type PropsWithChildren<P = {}> = P & {
3
+ /**
4
+ * A general `Component` has no implicit `children` prop. If desired, you can
5
+ * specify one as in `Component<{name: String, children: JSX.Element>}`.
6
+ */
7
+ export declare type Component<P = {}> = (props: P) => JSX.Element;
8
+ /**
9
+ * Extend props to forbid the `children` prop.
10
+ * Use this to prevent accidentally passing `children` to components that
11
+ * would silently throw them away.
12
+ */
13
+ export declare type VoidProps<P = {}> = P & {
14
+ children?: never;
15
+ };
16
+ /**
17
+ * `VoidComponent` forbids the `children` prop.
18
+ * Use this to prevent accidentally passing `children` to components that
19
+ * would silently throw them away.
20
+ */
21
+ export declare type VoidComponent<P = {}> = Component<VoidProps<P>>;
22
+ /**
23
+ * Extend props to allow an optional `children` prop with the usual
24
+ * type in JSX, `JSX.Element` (which allows elements, arrays, functions, etc.).
25
+ * Use this for components that you want to accept children.
26
+ */
27
+ export declare type ParentProps<P = {}> = P & {
4
28
  children?: JSX.Element;
5
29
  };
6
- export declare type Component<P = {}> = (props: PropsWithChildren<P>) => JSX.Element;
30
+ /**
31
+ * `ParentComponent` allows an optional `children` prop with the usual
32
+ * type in JSX, `JSX.Element` (which allows elements, arrays, functions, etc.).
33
+ * Use this for components that you want to accept children.
34
+ */
35
+ export declare type ParentComponent<P = {}> = Component<ParentProps<P>>;
36
+ /**
37
+ * Extend props to require a `children` prop with the specified type.
38
+ * Use this for components where you need a specific child type,
39
+ * typically a function that receives specific argument types.
40
+ * Note that all JSX <Elements> are of the type `JSX.Element`.
41
+ */
42
+ export declare type FlowProps<P = {}, C = JSX.Element> = P & {
43
+ children: C;
44
+ };
45
+ /**
46
+ * `FlowComponent` requires a `children` prop with the specified type.
47
+ * Use this for components where you need a specific child type,
48
+ * typically a function that receives specific argument types.
49
+ * Note that all JSX <Elements> are of the type `JSX.Element`.
50
+ */
51
+ export declare type FlowComponent<P = {}, C = JSX.Element> = Component<FlowProps<P, C>>;
52
+ /** @deprecated: use `ParentProps` instead */
53
+ export declare type PropsWithChildren<P = {}> = ParentProps<P>;
7
54
  /**
8
55
  * Takes the props of the passed component and returns its type
9
56
  *
@@ -12,7 +59,13 @@ export declare type Component<P = {}> = (props: PropsWithChildren<P>) => JSX.Ele
12
59
  * ComponentProps<'div'> // JSX.HTMLAttributes<HTMLDivElement>
13
60
  */
14
61
  export declare type ComponentProps<T extends keyof JSX.IntrinsicElements | Component<any>> = T extends Component<infer P> ? P : T extends keyof JSX.IntrinsicElements ? JSX.IntrinsicElements[T] : {};
15
- export declare function createComponent<T>(Comp: (props: T) => JSX.Element, props: T): JSX.Element;
62
+ /**
63
+ * Type of `props.ref`, for use in `Component` or `props` typing.
64
+ *
65
+ * @example Component<{ref: Ref<Element>}>
66
+ */
67
+ export declare type Ref<T> = T | ((val: T) => void);
68
+ export declare function createComponent<T>(Comp: Component<T>, props: T): JSX.Element;
16
69
  declare type UnboxLazy<T> = T extends () => infer U ? U : T;
17
70
  declare type BoxedTupleTypes<T extends any[]> = {
18
71
  [P in keyof T]: [UnboxLazy<T[P]>];
@@ -42,7 +42,7 @@ export declare function createContext<T>(defaultValue?: T): Context<T>;
42
42
  export declare function useContext<T>(context: Context<T>): T;
43
43
  export declare function getOwner(): Owner | null;
44
44
  export declare function children(fn: () => any): () => unknown;
45
- export declare function runWithOwner(o: Owner, fn: () => any): any;
45
+ export declare function runWithOwner<T>(o: Owner, fn: () => T): T;
46
46
  export declare function lookup(owner: Owner | null, key: symbol | string): any;
47
47
  export interface Task {
48
48
  id: number;
@@ -1,18 +1,26 @@
1
1
  import { Setter } from "./reactive";
2
2
  import type { JSX } from "../jsx";
3
- declare type PropsWithChildren<P> = P & {
3
+ export declare type Component<P = {}> = (props: P) => JSX.Element;
4
+ export declare type VoidProps<P = {}> = P & {
5
+ children?: never;
6
+ };
7
+ export declare type VoidComponent<P = {}> = Component<VoidProps<P>>;
8
+ export declare type ParentProps<P = {}> = P & {
4
9
  children?: JSX.Element;
5
10
  };
6
- export declare type Component<P = {}> = (props: PropsWithChildren<P>) => JSX.Element;
7
- declare type PossiblyWrapped<T> = {
8
- [P in keyof T]: T[P] | (() => T[P]);
11
+ export declare type ParentComponent<P = {}> = Component<ParentProps<P>>;
12
+ export declare type FlowProps<P = {}, C = JSX.Element> = P & {
13
+ children: C;
9
14
  };
15
+ export declare type FlowComponent<P = {}, C = JSX.Element> = Component<FlowProps<P, C>>;
16
+ export declare type Ref<T> = T | ((val: T) => void);
17
+ export declare type ComponentProps<T extends keyof JSX.IntrinsicElements | Component> = T extends Component<infer P> ? P : T extends keyof JSX.IntrinsicElements ? JSX.IntrinsicElements[T] : {};
10
18
  declare type SharedConfig = {
11
19
  context?: HydrationContext;
12
20
  };
13
21
  export declare const sharedConfig: SharedConfig;
14
22
  export declare function createUniqueId(): string;
15
- export declare function createComponent<T>(Comp: (props: T) => JSX.Element, props: PossiblyWrapped<T>): JSX.Element;
23
+ export declare function createComponent<T>(Comp: (props: T) => JSX.Element, props: T): JSX.Element;
16
24
  export declare function mergeProps<T, U>(source: T, source1: U): T & U;
17
25
  export declare function mergeProps<T, U, V>(source: T, source1: U, source2: V): T & U & V;
18
26
  export declare function mergeProps<T, U, V, W>(source: T, source1: U, source2: V, source3: W): T & U & V & W;
@@ -84,19 +92,25 @@ export declare type ResourceFetcherInfo<T> = {
84
92
  export declare type ResourceOptions<T> = undefined extends T ? {
85
93
  initialValue?: T;
86
94
  name?: string;
95
+ deferStream?: boolean;
87
96
  onHydrated?: <S, T>(k: S, info: ResourceFetcherInfo<T>) => void;
88
97
  } : {
89
98
  initialValue: T;
90
99
  name?: string;
100
+ deferStream?: boolean;
91
101
  onHydrated?: <S, T>(k: S, info: ResourceFetcherInfo<T>) => void;
92
102
  };
93
103
  export declare function createResource<T, S = true>(fetcher: ResourceFetcher<S, T>, options?: ResourceOptions<undefined>): ResourceReturn<T | undefined>;
94
104
  export declare function createResource<T, S = true>(fetcher: ResourceFetcher<S, T>, options: ResourceOptions<T>): ResourceReturn<T>;
95
105
  export declare function createResource<T, S>(source: ResourceSource<S>, fetcher: ResourceFetcher<S, T>, options?: ResourceOptions<undefined>): ResourceReturn<T | undefined>;
96
106
  export declare function createResource<T, S>(source: ResourceSource<S>, fetcher: ResourceFetcher<S, T>, options: ResourceOptions<T>): ResourceReturn<T>;
97
- export declare function lazy(fn: () => Promise<{
98
- default: any;
99
- }>): (props: any) => string;
107
+ export declare function lazy<T extends Component<any>>(fn: () => Promise<{
108
+ default: T;
109
+ }>): T & {
110
+ preload: () => Promise<{
111
+ default: T;
112
+ }>;
113
+ };
100
114
  export declare function enableScheduling(): void;
101
115
  export declare function enableHydration(): void;
102
116
  export declare function startTransition(fn: () => any): void;
@@ -104,7 +118,7 @@ export declare function useTransition(): [() => boolean, (fn: () => any) => void
104
118
  declare type HydrationContext = {
105
119
  id: string;
106
120
  count: number;
107
- writeResource?: (id: string, v: Promise<any> | any, error?: boolean) => void;
121
+ writeResource?: (id: string, v: Promise<any> | any, error?: boolean, deferStream?: boolean) => void;
108
122
  resources: Record<string, any>;
109
123
  suspense: Record<string, SuspenseContextType>;
110
124
  registerFragment: (v: string) => (v?: string, err?: any) => boolean;
@@ -120,5 +134,7 @@ export declare function SuspenseList(props: {
120
134
  export declare function Suspense(props: {
121
135
  fallback?: string;
122
136
  children: string;
123
- }): any;
137
+ }): string | number | boolean | Node | JSX.ArrayElement | JSX.FunctionElement | {
138
+ t: string;
139
+ } | null | undefined;
124
140
  export {};
@@ -269,8 +269,8 @@ function renderToStringAsync(code, options = {}) {
269
269
  nonce,
270
270
  writeResource(id, p, error) {
271
271
  if (error) return scripts += `_$HY.set("${id}", ${serializeError(p)});`;
272
- if (!p || typeof p !== "object" || !("then" in p)) return scripts += serializeSet(dedupe, id, p);
273
- p.then(d => scripts += serializeSet(dedupe, id, d)).catch(() => scripts += `_$HY.set("${id}", {});`);
272
+ if (!p || typeof p !== "object" || !("then" in p)) return (scripts += serializeSet(dedupe, id, p)) + ";";
273
+ p.then(d => scripts += serializeSet(dedupe, id, d) + ";").catch(() => scripts += `_$HY.set("${id}", {});`);
274
274
  }
275
275
  };
276
276
  const timeout = new Promise((_, reject) => setTimeout(() => reject("renderToString timed out"), timeoutMs));
@@ -318,6 +318,7 @@ function renderToStream(code, options = {}) {
318
318
  } = options;
319
319
  const tmp = [];
320
320
  const tasks = [];
321
+ const blockingResources = [];
321
322
  const registry = new Map();
322
323
  const dedupe = new WeakMap();
323
324
  const checkEnd = () => {
@@ -332,6 +333,13 @@ function renderToStream(code, options = {}) {
332
333
  completed = true;
333
334
  }
334
335
  };
336
+ const pushTask = task => {
337
+ tasks.push(task);
338
+ if (!scheduled) {
339
+ Promise.resolve().then(writeTasks);
340
+ scheduled = true;
341
+ }
342
+ };
335
343
  const writeTasks = () => {
336
344
  if (tasks.length && !completed) {
337
345
  buffer.write(`<script${nonce ? ` nonce="${nonce}"` : ""}>${tasks.join(";")}</script>`);
@@ -340,6 +348,7 @@ function renderToStream(code, options = {}) {
340
348
  scheduled = false;
341
349
  };
342
350
  let writable;
351
+ let firstFlushed = false;
343
352
  let completed = false;
344
353
  let scriptFlushed = false;
345
354
  let scheduled = true;
@@ -357,45 +366,45 @@ function renderToStream(code, options = {}) {
357
366
  suspense: {},
358
367
  assets: [],
359
368
  nonce,
360
- writeResource(id, p, error) {
361
- if (!scheduled) {
362
- Promise.resolve().then(writeTasks);
363
- scheduled = true;
364
- }
365
- if (error) return tasks.push(`_$HY.set("${id}", ${serializeError(p)})`);
366
- if (!p || typeof p !== "object" || !("then" in p)) return tasks.push(serializeSet(dedupe, id, p));
367
- tasks.push(`_$HY.init("${id}")`);
369
+ writeResource(id, p, error, wait) {
370
+ if (error) return pushTask(`_$HY.set("${id}", ${serializeError(p)})`);
371
+ if (!p || typeof p !== "object" || !("then" in p)) return pushTask(serializeSet(dedupe, id, p));
372
+ if (wait && !firstFlushed) blockingResources.push(p);else pushTask(`_$HY.init("${id}")`);
368
373
  p.then(d => {
369
- !completed && buffer.write(`<script${nonce ? ` nonce="${nonce}"` : ""}>${serializeSet(dedupe, id, d)}</script>`);
374
+ !completed && pushTask(serializeSet(dedupe, id, d));
370
375
  }).catch(() => {
371
- !completed && buffer.write(`<script${nonce ? ` nonce="${nonce}"` : ""}>_$HY.set("${id}", {})</script>`);
376
+ !completed && pushTask(`_$HY.set("${id}", {})`);
372
377
  });
373
378
  },
374
379
  registerFragment(key) {
375
- registry.set(key, []);
376
- if (!scheduled) {
377
- Promise.resolve().then(writeTasks);
378
- scheduled = true;
380
+ if (!registry.has(key)) {
381
+ registry.set(key, []);
382
+ pushTask(`_$HY.init("${key}")`);
379
383
  }
380
- tasks.push(`_$HY.init("${key}")`);
381
384
  return (value, error) => {
382
385
  if (registry.has(key)) {
383
386
  const keys = registry.get(key);
384
387
  registry.delete(key);
385
388
  if (waitForFragments(registry, key)) return;
386
389
  if ((value !== undefined || error) && !completed) {
387
- buffer.write(`<div hidden id="${key}">${value !== undefined ? value : " "}</div><script${nonce ? ` nonce="${nonce}"` : ""}>${!scriptFlushed ? REPLACE_SCRIPT : ""}${keys.length ? keys.map(k => `_$HY.unset("${k}");`) : ""}$df("${key}"${error ? "," + serializeError(error) : ""})</script>`);
388
- scriptFlushed = true;
390
+ if (!firstFlushed) {
391
+ Promise.resolve().then(() => html = replacePlaceholder(html, key, value !== undefined ? value : ""));
392
+ pushTask(`${keys.length ? keys.map(k => `_$HY.unset("${k}");`) : ""}_$HY.set("${key}",${error ? serializeError(error) : "null"})`);
393
+ } else {
394
+ buffer.write(`<div hidden id="${key}">${value !== undefined ? value : " "}</div>`);
395
+ pushTask(`${keys.length ? keys.map(k => `_$HY.unset("${k}")`).join(";") : ""}$df("${key}"${error ? "," + serializeError(error) : ""})${!scriptFlushed ? ";" + REPLACE_SCRIPT : ""}`);
396
+ scriptFlushed = true;
397
+ }
389
398
  }
390
399
  }
391
- checkEnd();
400
+ if (firstFlushed) checkEnd();
392
401
  return true;
393
402
  };
394
403
  }
395
404
  };
396
405
  let html = resolveSSRNode(escape(code()));
397
- html = injectAssets(solidJs.sharedConfig.context.assets, html);
398
- Promise.resolve().then(() => {
406
+ function doShell() {
407
+ html = injectAssets(solidJs.sharedConfig.context.assets, html);
399
408
  if (tasks.length) html = injectScripts(html, tasks.join(";"), nonce);
400
409
  buffer.write(html);
401
410
  tasks.length = 0;
@@ -405,29 +414,37 @@ function renderToStream(code, options = {}) {
405
414
  !completed && buffer.write(v);
406
415
  }
407
416
  });
408
- });
417
+ }
409
418
  return {
410
419
  pipe(w) {
411
- buffer = writable = w;
412
- tmp.forEach(chunk => buffer.write(chunk));
413
- if (completed) writable.end();else setTimeout(checkEnd);
420
+ Promise.allSettled(blockingResources).then(() => {
421
+ doShell();
422
+ buffer = writable = w;
423
+ tmp.forEach(chunk => buffer.write(chunk));
424
+ firstFlushed = true;
425
+ if (completed) writable.end();else setTimeout(checkEnd);
426
+ });
414
427
  },
415
428
  pipeTo(w) {
416
- const encoder = new TextEncoder();
417
- const writer = w.getWriter();
418
- writable = {
419
- end() {
420
- writer.releaseLock();
421
- w.close();
422
- }
423
- };
424
- buffer = {
425
- write(payload) {
426
- writer.write(encoder.encode(payload));
427
- }
428
- };
429
- tmp.forEach(chunk => buffer.write(chunk));
430
- if (completed) writable.end();else setTimeout(checkEnd);
429
+ Promise.allSettled(blockingResources).then(() => {
430
+ doShell();
431
+ const encoder = new TextEncoder();
432
+ const writer = w.getWriter();
433
+ writable = {
434
+ end() {
435
+ writer.releaseLock();
436
+ w.close();
437
+ }
438
+ };
439
+ buffer = {
440
+ write(payload) {
441
+ writer.write(encoder.encode(payload));
442
+ }
443
+ };
444
+ tmp.forEach(chunk => buffer.write(chunk));
445
+ firstFlushed = true;
446
+ if (completed) writable.end();else setTimeout(checkEnd);
447
+ });
431
448
  }
432
449
  };
433
450
  }
@@ -638,9 +655,26 @@ function waitForFragments(registry, key) {
638
655
  }
639
656
  function serializeSet(registry, key, value) {
640
657
  const exist = registry.get(value);
641
- if (exist) return `_$HY.set("${key}", _$HY.r["${exist}"][0]);`;
658
+ if (exist) return `_$HY.set("${key}", _$HY.r["${exist}"][0])`;
642
659
  value !== null && typeof value === "object" && registry.set(value, key);
643
- return `_$HY.set("${key}", ${devalue(value)});`;
660
+ return `_$HY.set("${key}", ${devalue(value)})`;
661
+ }
662
+ function replacePlaceholder(html, key, value) {
663
+ const nextRegex = /(<[/]?span[^>]*>)/g;
664
+ const marker = `<span id="pl-${key}">`;
665
+ const first = html.indexOf(marker);
666
+ if (first === -1) return html;
667
+ nextRegex.lastIndex = first + marker.length;
668
+ let match;
669
+ let open = 0,
670
+ close = 0;
671
+ while (match = nextRegex.exec(html)) {
672
+ if (match[0][1] === "/") {
673
+ close++;
674
+ if (close > open) break;
675
+ } else open++;
676
+ }
677
+ return html.slice(0, first) + value + html.slice(nextRegex.lastIndex);
644
678
  }
645
679
  function pipeToNodeWritable(code, writable, options = {}) {
646
680
  if (options.onReady) {
@@ -266,8 +266,8 @@ function renderToStringAsync(code, options = {}) {
266
266
  nonce,
267
267
  writeResource(id, p, error) {
268
268
  if (error) return scripts += `_$HY.set("${id}", ${serializeError(p)});`;
269
- if (!p || typeof p !== "object" || !("then" in p)) return scripts += serializeSet(dedupe, id, p);
270
- p.then(d => scripts += serializeSet(dedupe, id, d)).catch(() => scripts += `_$HY.set("${id}", {});`);
269
+ if (!p || typeof p !== "object" || !("then" in p)) return (scripts += serializeSet(dedupe, id, p)) + ";";
270
+ p.then(d => scripts += serializeSet(dedupe, id, d) + ";").catch(() => scripts += `_$HY.set("${id}", {});`);
271
271
  }
272
272
  };
273
273
  const timeout = new Promise((_, reject) => setTimeout(() => reject("renderToString timed out"), timeoutMs));
@@ -315,6 +315,7 @@ function renderToStream(code, options = {}) {
315
315
  } = options;
316
316
  const tmp = [];
317
317
  const tasks = [];
318
+ const blockingResources = [];
318
319
  const registry = new Map();
319
320
  const dedupe = new WeakMap();
320
321
  const checkEnd = () => {
@@ -329,6 +330,13 @@ function renderToStream(code, options = {}) {
329
330
  completed = true;
330
331
  }
331
332
  };
333
+ const pushTask = task => {
334
+ tasks.push(task);
335
+ if (!scheduled) {
336
+ Promise.resolve().then(writeTasks);
337
+ scheduled = true;
338
+ }
339
+ };
332
340
  const writeTasks = () => {
333
341
  if (tasks.length && !completed) {
334
342
  buffer.write(`<script${nonce ? ` nonce="${nonce}"` : ""}>${tasks.join(";")}</script>`);
@@ -337,6 +345,7 @@ function renderToStream(code, options = {}) {
337
345
  scheduled = false;
338
346
  };
339
347
  let writable;
348
+ let firstFlushed = false;
340
349
  let completed = false;
341
350
  let scriptFlushed = false;
342
351
  let scheduled = true;
@@ -354,45 +363,45 @@ function renderToStream(code, options = {}) {
354
363
  suspense: {},
355
364
  assets: [],
356
365
  nonce,
357
- writeResource(id, p, error) {
358
- if (!scheduled) {
359
- Promise.resolve().then(writeTasks);
360
- scheduled = true;
361
- }
362
- if (error) return tasks.push(`_$HY.set("${id}", ${serializeError(p)})`);
363
- if (!p || typeof p !== "object" || !("then" in p)) return tasks.push(serializeSet(dedupe, id, p));
364
- tasks.push(`_$HY.init("${id}")`);
366
+ writeResource(id, p, error, wait) {
367
+ if (error) return pushTask(`_$HY.set("${id}", ${serializeError(p)})`);
368
+ if (!p || typeof p !== "object" || !("then" in p)) return pushTask(serializeSet(dedupe, id, p));
369
+ if (wait && !firstFlushed) blockingResources.push(p);else pushTask(`_$HY.init("${id}")`);
365
370
  p.then(d => {
366
- !completed && buffer.write(`<script${nonce ? ` nonce="${nonce}"` : ""}>${serializeSet(dedupe, id, d)}</script>`);
371
+ !completed && pushTask(serializeSet(dedupe, id, d));
367
372
  }).catch(() => {
368
- !completed && buffer.write(`<script${nonce ? ` nonce="${nonce}"` : ""}>_$HY.set("${id}", {})</script>`);
373
+ !completed && pushTask(`_$HY.set("${id}", {})`);
369
374
  });
370
375
  },
371
376
  registerFragment(key) {
372
- registry.set(key, []);
373
- if (!scheduled) {
374
- Promise.resolve().then(writeTasks);
375
- scheduled = true;
377
+ if (!registry.has(key)) {
378
+ registry.set(key, []);
379
+ pushTask(`_$HY.init("${key}")`);
376
380
  }
377
- tasks.push(`_$HY.init("${key}")`);
378
381
  return (value, error) => {
379
382
  if (registry.has(key)) {
380
383
  const keys = registry.get(key);
381
384
  registry.delete(key);
382
385
  if (waitForFragments(registry, key)) return;
383
386
  if ((value !== undefined || error) && !completed) {
384
- buffer.write(`<div hidden id="${key}">${value !== undefined ? value : " "}</div><script${nonce ? ` nonce="${nonce}"` : ""}>${!scriptFlushed ? REPLACE_SCRIPT : ""}${keys.length ? keys.map(k => `_$HY.unset("${k}");`) : ""}$df("${key}"${error ? "," + serializeError(error) : ""})</script>`);
385
- scriptFlushed = true;
387
+ if (!firstFlushed) {
388
+ Promise.resolve().then(() => html = replacePlaceholder(html, key, value !== undefined ? value : ""));
389
+ pushTask(`${keys.length ? keys.map(k => `_$HY.unset("${k}");`) : ""}_$HY.set("${key}",${error ? serializeError(error) : "null"})`);
390
+ } else {
391
+ buffer.write(`<div hidden id="${key}">${value !== undefined ? value : " "}</div>`);
392
+ pushTask(`${keys.length ? keys.map(k => `_$HY.unset("${k}")`).join(";") : ""}$df("${key}"${error ? "," + serializeError(error) : ""})${!scriptFlushed ? ";" + REPLACE_SCRIPT : ""}`);
393
+ scriptFlushed = true;
394
+ }
386
395
  }
387
396
  }
388
- checkEnd();
397
+ if (firstFlushed) checkEnd();
389
398
  return true;
390
399
  };
391
400
  }
392
401
  };
393
402
  let html = resolveSSRNode(escape(code()));
394
- html = injectAssets(sharedConfig.context.assets, html);
395
- Promise.resolve().then(() => {
403
+ function doShell() {
404
+ html = injectAssets(sharedConfig.context.assets, html);
396
405
  if (tasks.length) html = injectScripts(html, tasks.join(";"), nonce);
397
406
  buffer.write(html);
398
407
  tasks.length = 0;
@@ -402,29 +411,37 @@ function renderToStream(code, options = {}) {
402
411
  !completed && buffer.write(v);
403
412
  }
404
413
  });
405
- });
414
+ }
406
415
  return {
407
416
  pipe(w) {
408
- buffer = writable = w;
409
- tmp.forEach(chunk => buffer.write(chunk));
410
- if (completed) writable.end();else setTimeout(checkEnd);
417
+ Promise.allSettled(blockingResources).then(() => {
418
+ doShell();
419
+ buffer = writable = w;
420
+ tmp.forEach(chunk => buffer.write(chunk));
421
+ firstFlushed = true;
422
+ if (completed) writable.end();else setTimeout(checkEnd);
423
+ });
411
424
  },
412
425
  pipeTo(w) {
413
- const encoder = new TextEncoder();
414
- const writer = w.getWriter();
415
- writable = {
416
- end() {
417
- writer.releaseLock();
418
- w.close();
419
- }
420
- };
421
- buffer = {
422
- write(payload) {
423
- writer.write(encoder.encode(payload));
424
- }
425
- };
426
- tmp.forEach(chunk => buffer.write(chunk));
427
- if (completed) writable.end();else setTimeout(checkEnd);
426
+ Promise.allSettled(blockingResources).then(() => {
427
+ doShell();
428
+ const encoder = new TextEncoder();
429
+ const writer = w.getWriter();
430
+ writable = {
431
+ end() {
432
+ writer.releaseLock();
433
+ w.close();
434
+ }
435
+ };
436
+ buffer = {
437
+ write(payload) {
438
+ writer.write(encoder.encode(payload));
439
+ }
440
+ };
441
+ tmp.forEach(chunk => buffer.write(chunk));
442
+ firstFlushed = true;
443
+ if (completed) writable.end();else setTimeout(checkEnd);
444
+ });
428
445
  }
429
446
  };
430
447
  }
@@ -635,9 +652,26 @@ function waitForFragments(registry, key) {
635
652
  }
636
653
  function serializeSet(registry, key, value) {
637
654
  const exist = registry.get(value);
638
- if (exist) return `_$HY.set("${key}", _$HY.r["${exist}"][0]);`;
655
+ if (exist) return `_$HY.set("${key}", _$HY.r["${exist}"][0])`;
639
656
  value !== null && typeof value === "object" && registry.set(value, key);
640
- return `_$HY.set("${key}", ${devalue(value)});`;
657
+ return `_$HY.set("${key}", ${devalue(value)})`;
658
+ }
659
+ function replacePlaceholder(html, key, value) {
660
+ const nextRegex = /(<[/]?span[^>]*>)/g;
661
+ const marker = `<span id="pl-${key}">`;
662
+ const first = html.indexOf(marker);
663
+ if (first === -1) return html;
664
+ nextRegex.lastIndex = first + marker.length;
665
+ let match;
666
+ let open = 0,
667
+ close = 0;
668
+ while (match = nextRegex.exec(html)) {
669
+ if (match[0][1] === "/") {
670
+ close++;
671
+ if (close > open) break;
672
+ } else open++;
673
+ }
674
+ return html.slice(0, first) + value + html.slice(nextRegex.lastIndex);
641
675
  }
642
676
  function pipeToNodeWritable(code, writable, options = {}) {
643
677
  if (options.onReady) {
package/jsx-runtime.d.ts DELETED
@@ -1 +0,0 @@
1
- export * from "./types/jsx"