@qwik.dev/core 2.0.0-alpha.1 → 2.0.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/core.mjs CHANGED
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * @license
3
- * @qwik.dev/core 2.0.0-alpha.1-dev+10f5414
3
+ * @qwik.dev/core 2.0.0-alpha.2-dev+58b6f8d
4
4
  * Copyright QwikDev. All Rights Reserved.
5
5
  * Use of this source code is governed by an MIT-style license that can be
6
6
  * found in the LICENSE file at https://github.com/QwikDev/qwik/blob/main/LICENSE
@@ -1264,6 +1264,12 @@ function clearEffects(subscriber, value) {
1264
1264
  return subscriptionRemoved;
1265
1265
  }
1266
1266
 
1267
+ /**
1268
+ * Special value used to mark that a given signal needs to be computed. This is essentially a
1269
+ * "marked as dirty" flag.
1270
+ */
1271
+ const NEEDS_COMPUTATION = Symbol('invalid');
1272
+
1267
1273
  /**
1268
1274
  * @file
1269
1275
  *
@@ -1278,11 +1284,6 @@ function clearEffects(subscriber, value) {
1278
1284
  * - It is `Readonly` because it is computed.
1279
1285
  */
1280
1286
  const DEBUG = false;
1281
- /**
1282
- * Special value used to mark that a given signal needs to be computed. This is essentially a
1283
- * "marked as dirty" flag.
1284
- */
1285
- const NEEDS_COMPUTATION = Symbol('invalid');
1286
1287
  // eslint-disable-next-line no-console
1287
1288
  const log = (...args) => console.log('SIGNAL', ...args.map(qwikDebugToString));
1288
1289
  const throwIfQRLNotResolved = (qrl) => {
@@ -2176,6 +2177,15 @@ class StoreHandler {
2176
2177
  if (prop === STORE_TARGET) {
2177
2178
  return true;
2178
2179
  }
2180
+ if (typeof prop === 'string') {
2181
+ const ctx = tryGetInvokeContext();
2182
+ if (ctx) {
2183
+ const effectSubscriber = ctx.$effectSubscriber$;
2184
+ if (effectSubscriber) {
2185
+ addEffect(target, Array.isArray(target) ? STORE_ARRAY_PROP : prop, this, effectSubscriber);
2186
+ }
2187
+ }
2188
+ }
2179
2189
  return Object.prototype.hasOwnProperty.call(target, prop);
2180
2190
  }
2181
2191
  ownKeys(target) {
@@ -4453,7 +4463,10 @@ function choreComparator(a, b, shouldThrowOnHostMismatch) {
4453
4463
  // On server we can't schedule task for a different host!
4454
4464
  // Server is SSR, and therefore scheduling for anything but the current host
4455
4465
  // implies that things need to be re-run nad that is not supported because of streaming.
4456
- const errorMessage = 'SERVER: during HTML streaming, it is not possible to cause a re-run of tasks on a different host';
4466
+ const errorMessage = `SERVER: during HTML streaming, re-running tasks on a different host is not allowed.
4467
+ You are attempting to change a state that has already been streamed to the client.
4468
+ This can lead to inconsistencies between Server-Side Rendering (SSR) and Client-Side Rendering (CSR).
4469
+ Problematic Node: ${aHost.toString()}`;
4457
4470
  if (shouldThrowOnHostMismatch) {
4458
4471
  throwErrorAndStop(errorMessage);
4459
4472
  }
@@ -4520,7 +4533,7 @@ function sortedInsert(sortedArray, value) {
4520
4533
  *
4521
4534
  * @public
4522
4535
  */
4523
- const version = "2.0.0-alpha.1-dev+10f5414";
4536
+ const version = "2.0.0-alpha.2-dev+58b6f8d";
4524
4537
 
4525
4538
  /** @internal */
4526
4539
  class _SharedContainer {
@@ -4547,8 +4560,8 @@ class _SharedContainer {
4547
4560
  trackSignalValue(signal, subscriber, property, data) {
4548
4561
  return trackSignal(() => signal.value, subscriber, property, this, data);
4549
4562
  }
4550
- serializationCtxFactory(NodeConstructor, symbolToChunkResolver, writer, prepVNodeData) {
4551
- return createSerializationContext(NodeConstructor, symbolToChunkResolver, this.getHostProp.bind(this), this.setHostProp.bind(this), this.$storeProxyMap$, writer, prepVNodeData);
4563
+ serializationCtxFactory(NodeConstructor, DomRefConstructor, symbolToChunkResolver, writer, prepVNodeData) {
4564
+ return createSerializationContext(NodeConstructor, DomRefConstructor, symbolToChunkResolver, this.getHostProp.bind(this), this.setHostProp.bind(this), this.$storeProxyMap$, writer, prepVNodeData);
4552
4565
  }
4553
4566
  }
4554
4567
 
@@ -8378,13 +8391,6 @@ function inflateQRL(container, qrl) {
8378
8391
  }
8379
8392
  return qrl;
8380
8393
  }
8381
- /** A ref to a DOM element */
8382
- class DomVRef {
8383
- id;
8384
- constructor(id) {
8385
- this.id = id;
8386
- }
8387
- }
8388
8394
  const createSerializationContext = (
8389
8395
  /**
8390
8396
  * Node constructor, for instanceof checks.
@@ -8392,7 +8398,9 @@ const createSerializationContext = (
8392
8398
  * A node constructor can be null. For example on the client we can't serialize DOM nodes as
8393
8399
  * server will not know what to do with them.
8394
8400
  */
8395
- NodeConstructor, symbolToChunkResolver, getProp, setProp, storeProxyMap, writer,
8401
+ NodeConstructor,
8402
+ /** DomRef constructor, for instanceof checks. */
8403
+ DomRefConstructor, symbolToChunkResolver, getProp, setProp, storeProxyMap, writer,
8396
8404
  // temporary until we serdes the vnode data here
8397
8405
  prepVNodeData) => {
8398
8406
  if (!writer) {
@@ -8418,11 +8426,13 @@ prepVNodeData) => {
8418
8426
  return id;
8419
8427
  };
8420
8428
  const isSsrNode = (NodeConstructor ? (obj) => obj instanceof NodeConstructor : () => false);
8429
+ const isDomRef = (DomRefConstructor ? (obj) => obj instanceof DomRefConstructor : () => false);
8421
8430
  return {
8422
8431
  $serialize$() {
8423
8432
  serialize(this);
8424
8433
  },
8425
8434
  $isSsrNode$: isSsrNode,
8435
+ $isDomRef$: isDomRef,
8426
8436
  $symbolToChunkResolver$: symbolToChunkResolver,
8427
8437
  $wasSeen$,
8428
8438
  $roots$: roots,
@@ -8568,6 +8578,9 @@ prepVNodeData) => {
8568
8578
  else if (isSsrNode(obj)) {
8569
8579
  discoveredValues.push(obj.vnodeData);
8570
8580
  }
8581
+ else if (isDomRef(obj)) {
8582
+ discoveredValues.push(obj.id);
8583
+ }
8571
8584
  else if (isJSXNode(obj)) {
8572
8585
  discoveredValues.push(obj.type, obj.props, obj.constProps, obj.children);
8573
8586
  }
@@ -8641,7 +8654,7 @@ const promiseResults = new WeakMap();
8641
8654
  * - Therefore root indexes need to be doubled to get the actual index.
8642
8655
  */
8643
8656
  function serialize(serializationContext) {
8644
- const { $writer$, $isSsrNode$, $setProp$, $storeProxyMap$ } = serializationContext;
8657
+ const { $writer$, $isSsrNode$, $isDomRef$, $setProp$, $storeProxyMap$ } = serializationContext;
8645
8658
  let depth = -1;
8646
8659
  // Skip the type for the roots output
8647
8660
  let writeType = false;
@@ -8863,7 +8876,7 @@ function serialize(serializationContext) {
8863
8876
  output(TypeIds.Object, out);
8864
8877
  }
8865
8878
  }
8866
- else if (value instanceof DomVRef) {
8879
+ else if ($isDomRef$(value)) {
8867
8880
  output(TypeIds.RefVNode, value.id);
8868
8881
  }
8869
8882
  else if (value instanceof Signal) {
@@ -8871,15 +8884,10 @@ function serialize(serializationContext) {
8871
8884
  * Special case: when a Signal value is an SSRNode, it always needs to be a DOM ref instead.
8872
8885
  * It can never be meant to become a vNode, because vNodes are internal only.
8873
8886
  */
8874
- let v = value instanceof ComputedSignal &&
8887
+ const v = value instanceof ComputedSignal &&
8875
8888
  (value.$invalid$ || fastSkipSerialize(value.$untrackedValue$))
8876
8889
  ? NEEDS_COMPUTATION
8877
8890
  : value.$untrackedValue$;
8878
- if ($isSsrNode$(v)) {
8879
- // TODO maybe we don't need to store all vnode data if it's only a ref
8880
- serializationContext.$addRoot$(v);
8881
- v = new DomVRef(v.id);
8882
- }
8883
8891
  if (value instanceof WrappedSignal) {
8884
8892
  output(TypeIds.WrappedSignal, [
8885
8893
  ...serializeWrappingFn(serializationContext, value),
@@ -9096,7 +9104,7 @@ function qrlToString(serializationContext, value) {
9096
9104
  * @internal
9097
9105
  */
9098
9106
  async function _serialize(data) {
9099
- const serializationContext = createSerializationContext(null, () => '', () => '', () => { }, new WeakMap());
9107
+ const serializationContext = createSerializationContext(null, null, () => '', () => '', () => { }, new WeakMap());
9100
9108
  for (const root of data) {
9101
9109
  serializationContext.$addRoot$(root);
9102
9110
  }
@@ -9491,8 +9499,8 @@ const createQRL = (chunk, symbol, symbolRef, symbolFn, capture, captureRef, refS
9491
9499
  }
9492
9500
  let _containerEl;
9493
9501
  const qrl = async function (...args) {
9494
- const fn = invokeFn.call(this, tryGetInvokeContext());
9495
- const result = await fn(...args);
9502
+ const boundedFn = bindFnToContext.call(this, tryGetInvokeContext());
9503
+ const result = await boundedFn(...args);
9496
9504
  return result;
9497
9505
  };
9498
9506
  const setContainer = (el) => {
@@ -9501,6 +9509,34 @@ const createQRL = (chunk, symbol, symbolRef, symbolFn, capture, captureRef, refS
9501
9509
  }
9502
9510
  return _containerEl;
9503
9511
  };
9512
+ function bindFnToContext(currentCtx, beforeFn) {
9513
+ // Note that we bind the current `this`
9514
+ return (...args) => maybeThen(resolveLazy(), (fn) => {
9515
+ if (!isFunction(fn)) {
9516
+ throw qError(QError_qrlIsNotFunction);
9517
+ }
9518
+ if (beforeFn && beforeFn() === false) {
9519
+ return;
9520
+ }
9521
+ const context = createOrReuseInvocationContext(currentCtx);
9522
+ const prevQrl = context.$qrl$;
9523
+ const prevEvent = context.$event$;
9524
+ // Note that we set the qrl here instead of in wrapFn because
9525
+ // it is possible we're called on a copied qrl
9526
+ context.$qrl$ = qrl;
9527
+ context.$event$ ||= this;
9528
+ try {
9529
+ return invoke.call(this, context, fn, ...args);
9530
+ }
9531
+ finally {
9532
+ context.$qrl$ = prevQrl;
9533
+ context.$event$ = prevEvent;
9534
+ }
9535
+ });
9536
+ }
9537
+ const resolveLazy = (containerEl) => {
9538
+ return symbolRef !== null ? symbolRef : resolve(containerEl);
9539
+ };
9504
9540
  // Wrap functions to provide their lexical scope
9505
9541
  const wrapFn = (fn) => {
9506
9542
  if (typeof fn !== 'function' || (!capture?.length && !captureRef?.length)) {
@@ -9553,34 +9589,6 @@ const createQRL = (chunk, symbol, symbolRef, symbolFn, capture, captureRef, refS
9553
9589
  }
9554
9590
  return symbolRef;
9555
9591
  };
9556
- const resolveLazy = (containerEl) => {
9557
- return symbolRef !== null ? symbolRef : resolve(containerEl);
9558
- };
9559
- function invokeFn(currentCtx, beforeFn) {
9560
- // Note that we bind the current `this`
9561
- return (...args) => maybeThen(resolveLazy(), (f) => {
9562
- if (!isFunction(f)) {
9563
- throw qError(QError_qrlIsNotFunction);
9564
- }
9565
- if (beforeFn && beforeFn() === false) {
9566
- return;
9567
- }
9568
- const context = createOrReuseInvocationContext(currentCtx);
9569
- const prevQrl = context.$qrl$;
9570
- const prevEvent = context.$event$;
9571
- // Note that we set the qrl here instead of in wrapFn because
9572
- // it is possible we're called on a copied qrl
9573
- context.$qrl$ = qrl;
9574
- context.$event$ ||= this;
9575
- try {
9576
- return invoke.call(this, context, f, ...args);
9577
- }
9578
- finally {
9579
- context.$qrl$ = prevQrl;
9580
- context.$event$ = prevEvent;
9581
- }
9582
- });
9583
- }
9584
9592
  const createOrReuseInvocationContext = (invoke) => {
9585
9593
  if (invoke == null) {
9586
9594
  return newInvokeContext();
@@ -9605,7 +9613,7 @@ const createQRL = (chunk, symbol, symbolRef, symbolFn, capture, captureRef, refS
9605
9613
  $symbol$: symbol,
9606
9614
  $refSymbol$: refSymbol,
9607
9615
  $hash$: hash,
9608
- getFn: invokeFn,
9616
+ getFn: bindFnToContext,
9609
9617
  $capture$: capture,
9610
9618
  $captureRef$: captureRef,
9611
9619
  dev: null,