@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.
@@ -552,6 +552,10 @@ declare interface Container {
552
552
  nodeType: number;
553
553
  id: string;
554
554
  };
555
+ } | null, DomRefConstructor: {
556
+ new (...rest: any[]): {
557
+ id: string;
558
+ };
555
559
  } | null, symbolToChunkResolver: SymbolToChunkResolver, writer?: StreamWriter): SerializationContext;
556
560
  }
557
561
 
@@ -885,6 +889,10 @@ declare class DomContainer extends _SharedContainer implements ClientContainer {
885
889
  export { DomContainer }
886
890
  export { DomContainer as _DomContainer }
887
891
 
892
+ declare type DomRef = {
893
+ id: string;
894
+ };
895
+
888
896
  /** @public */
889
897
  export declare type EagernessOptions = 'visible' | 'load' | 'idle';
890
898
 
@@ -2278,6 +2286,7 @@ declare interface SerializationContext {
2278
2286
  $addSyncFn$($funcStr$: string | null, argsCount: number, fn: Function): number;
2279
2287
  $breakCircularDepsAndAwaitPromises$: () => ValueOrPromise<void>;
2280
2288
  $isSsrNode$: (obj: unknown) => obj is SsrNode;
2289
+ $isDomRef$: (obj: unknown) => obj is DomRef;
2281
2290
  $writer$: StreamWriter_2;
2282
2291
  $syncFns$: string[];
2283
2292
  $eventQrls$: Set<QRL>;
@@ -2327,6 +2336,10 @@ export declare abstract class _SharedContainer implements Container {
2327
2336
  nodeType: number;
2328
2337
  id: string;
2329
2338
  };
2339
+ } | null, DomRefConstructor: {
2340
+ new (...rest: any[]): {
2341
+ id: string;
2342
+ };
2330
2343
  } | null, symbolToChunkResolver: SymbolToChunkResolver, writer?: StreamWriter, prepVNodeData?: (vNode: any) => void): SerializationContext;
2331
2344
  abstract ensureProjectionResolved(host: HostElement): void;
2332
2345
  abstract processJsx(host: HostElement, jsx: JSXOutput): ValueOrPromise<void>;
@@ -3708,7 +3721,7 @@ export declare const _VAR_PROPS: unique symbol;
3708
3721
  export declare const _verifySerializable: <T>(value: T, preMessage?: string) => T;
3709
3722
 
3710
3723
  /**
3711
- * 2.0.0-alpha.1-dev+10f5414
3724
+ * 2.0.0-alpha.2-dev+58b6f8d
3712
3725
  *
3713
3726
  * @public
3714
3727
  */
package/dist/core.cjs 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
@@ -1267,6 +1267,12 @@
1267
1267
  return subscriptionRemoved;
1268
1268
  }
1269
1269
 
1270
+ /**
1271
+ * Special value used to mark that a given signal needs to be computed. This is essentially a
1272
+ * "marked as dirty" flag.
1273
+ */
1274
+ const NEEDS_COMPUTATION = Symbol('invalid');
1275
+
1270
1276
  /**
1271
1277
  * @file
1272
1278
  *
@@ -1281,11 +1287,6 @@
1281
1287
  * - It is `Readonly` because it is computed.
1282
1288
  */
1283
1289
  const DEBUG = false;
1284
- /**
1285
- * Special value used to mark that a given signal needs to be computed. This is essentially a
1286
- * "marked as dirty" flag.
1287
- */
1288
- const NEEDS_COMPUTATION = Symbol('invalid');
1289
1290
  // eslint-disable-next-line no-console
1290
1291
  const log = (...args) => console.log('SIGNAL', ...args.map(qwikDebugToString));
1291
1292
  const throwIfQRLNotResolved = (qrl) => {
@@ -2179,6 +2180,15 @@
2179
2180
  if (prop === STORE_TARGET) {
2180
2181
  return true;
2181
2182
  }
2183
+ if (typeof prop === 'string') {
2184
+ const ctx = tryGetInvokeContext();
2185
+ if (ctx) {
2186
+ const effectSubscriber = ctx.$effectSubscriber$;
2187
+ if (effectSubscriber) {
2188
+ addEffect(target, Array.isArray(target) ? STORE_ARRAY_PROP : prop, this, effectSubscriber);
2189
+ }
2190
+ }
2191
+ }
2182
2192
  return Object.prototype.hasOwnProperty.call(target, prop);
2183
2193
  }
2184
2194
  ownKeys(target) {
@@ -4456,7 +4466,10 @@
4456
4466
  // On server we can't schedule task for a different host!
4457
4467
  // Server is SSR, and therefore scheduling for anything but the current host
4458
4468
  // implies that things need to be re-run nad that is not supported because of streaming.
4459
- const errorMessage = 'SERVER: during HTML streaming, it is not possible to cause a re-run of tasks on a different host';
4469
+ const errorMessage = `SERVER: during HTML streaming, re-running tasks on a different host is not allowed.
4470
+ You are attempting to change a state that has already been streamed to the client.
4471
+ This can lead to inconsistencies between Server-Side Rendering (SSR) and Client-Side Rendering (CSR).
4472
+ Problematic Node: ${aHost.toString()}`;
4460
4473
  if (shouldThrowOnHostMismatch) {
4461
4474
  throwErrorAndStop(errorMessage);
4462
4475
  }
@@ -4523,7 +4536,7 @@
4523
4536
  *
4524
4537
  * @public
4525
4538
  */
4526
- const version = "2.0.0-alpha.1-dev+10f5414";
4539
+ const version = "2.0.0-alpha.2-dev+58b6f8d";
4527
4540
 
4528
4541
  /** @internal */
4529
4542
  class _SharedContainer {
@@ -4550,8 +4563,8 @@
4550
4563
  trackSignalValue(signal, subscriber, property, data) {
4551
4564
  return trackSignal(() => signal.value, subscriber, property, this, data);
4552
4565
  }
4553
- serializationCtxFactory(NodeConstructor, symbolToChunkResolver, writer, prepVNodeData) {
4554
- return createSerializationContext(NodeConstructor, symbolToChunkResolver, this.getHostProp.bind(this), this.setHostProp.bind(this), this.$storeProxyMap$, writer, prepVNodeData);
4566
+ serializationCtxFactory(NodeConstructor, DomRefConstructor, symbolToChunkResolver, writer, prepVNodeData) {
4567
+ return createSerializationContext(NodeConstructor, DomRefConstructor, symbolToChunkResolver, this.getHostProp.bind(this), this.setHostProp.bind(this), this.$storeProxyMap$, writer, prepVNodeData);
4555
4568
  }
4556
4569
  }
4557
4570
 
@@ -8381,13 +8394,6 @@
8381
8394
  }
8382
8395
  return qrl;
8383
8396
  }
8384
- /** A ref to a DOM element */
8385
- class DomVRef {
8386
- id;
8387
- constructor(id) {
8388
- this.id = id;
8389
- }
8390
- }
8391
8397
  const createSerializationContext = (
8392
8398
  /**
8393
8399
  * Node constructor, for instanceof checks.
@@ -8395,7 +8401,9 @@
8395
8401
  * A node constructor can be null. For example on the client we can't serialize DOM nodes as
8396
8402
  * server will not know what to do with them.
8397
8403
  */
8398
- NodeConstructor, symbolToChunkResolver, getProp, setProp, storeProxyMap, writer,
8404
+ NodeConstructor,
8405
+ /** DomRef constructor, for instanceof checks. */
8406
+ DomRefConstructor, symbolToChunkResolver, getProp, setProp, storeProxyMap, writer,
8399
8407
  // temporary until we serdes the vnode data here
8400
8408
  prepVNodeData) => {
8401
8409
  if (!writer) {
@@ -8421,11 +8429,13 @@
8421
8429
  return id;
8422
8430
  };
8423
8431
  const isSsrNode = (NodeConstructor ? (obj) => obj instanceof NodeConstructor : () => false);
8432
+ const isDomRef = (DomRefConstructor ? (obj) => obj instanceof DomRefConstructor : () => false);
8424
8433
  return {
8425
8434
  $serialize$() {
8426
8435
  serialize(this);
8427
8436
  },
8428
8437
  $isSsrNode$: isSsrNode,
8438
+ $isDomRef$: isDomRef,
8429
8439
  $symbolToChunkResolver$: symbolToChunkResolver,
8430
8440
  $wasSeen$,
8431
8441
  $roots$: roots,
@@ -8571,6 +8581,9 @@
8571
8581
  else if (isSsrNode(obj)) {
8572
8582
  discoveredValues.push(obj.vnodeData);
8573
8583
  }
8584
+ else if (isDomRef(obj)) {
8585
+ discoveredValues.push(obj.id);
8586
+ }
8574
8587
  else if (isJSXNode(obj)) {
8575
8588
  discoveredValues.push(obj.type, obj.props, obj.constProps, obj.children);
8576
8589
  }
@@ -8644,7 +8657,7 @@
8644
8657
  * - Therefore root indexes need to be doubled to get the actual index.
8645
8658
  */
8646
8659
  function serialize(serializationContext) {
8647
- const { $writer$, $isSsrNode$, $setProp$, $storeProxyMap$ } = serializationContext;
8660
+ const { $writer$, $isSsrNode$, $isDomRef$, $setProp$, $storeProxyMap$ } = serializationContext;
8648
8661
  let depth = -1;
8649
8662
  // Skip the type for the roots output
8650
8663
  let writeType = false;
@@ -8866,7 +8879,7 @@
8866
8879
  output(TypeIds.Object, out);
8867
8880
  }
8868
8881
  }
8869
- else if (value instanceof DomVRef) {
8882
+ else if ($isDomRef$(value)) {
8870
8883
  output(TypeIds.RefVNode, value.id);
8871
8884
  }
8872
8885
  else if (value instanceof Signal) {
@@ -8874,15 +8887,10 @@
8874
8887
  * Special case: when a Signal value is an SSRNode, it always needs to be a DOM ref instead.
8875
8888
  * It can never be meant to become a vNode, because vNodes are internal only.
8876
8889
  */
8877
- let v = value instanceof ComputedSignal &&
8890
+ const v = value instanceof ComputedSignal &&
8878
8891
  (value.$invalid$ || fastSkipSerialize(value.$untrackedValue$))
8879
8892
  ? NEEDS_COMPUTATION
8880
8893
  : value.$untrackedValue$;
8881
- if ($isSsrNode$(v)) {
8882
- // TODO maybe we don't need to store all vnode data if it's only a ref
8883
- serializationContext.$addRoot$(v);
8884
- v = new DomVRef(v.id);
8885
- }
8886
8894
  if (value instanceof WrappedSignal) {
8887
8895
  output(TypeIds.WrappedSignal, [
8888
8896
  ...serializeWrappingFn(serializationContext, value),
@@ -9099,7 +9107,7 @@
9099
9107
  * @internal
9100
9108
  */
9101
9109
  async function _serialize(data) {
9102
- const serializationContext = createSerializationContext(null, () => '', () => '', () => { }, new WeakMap());
9110
+ const serializationContext = createSerializationContext(null, null, () => '', () => '', () => { }, new WeakMap());
9103
9111
  for (const root of data) {
9104
9112
  serializationContext.$addRoot$(root);
9105
9113
  }
@@ -9494,8 +9502,8 @@
9494
9502
  }
9495
9503
  let _containerEl;
9496
9504
  const qrl = async function (...args) {
9497
- const fn = invokeFn.call(this, tryGetInvokeContext());
9498
- const result = await fn(...args);
9505
+ const boundedFn = bindFnToContext.call(this, tryGetInvokeContext());
9506
+ const result = await boundedFn(...args);
9499
9507
  return result;
9500
9508
  };
9501
9509
  const setContainer = (el) => {
@@ -9504,6 +9512,34 @@
9504
9512
  }
9505
9513
  return _containerEl;
9506
9514
  };
9515
+ function bindFnToContext(currentCtx, beforeFn) {
9516
+ // Note that we bind the current `this`
9517
+ return (...args) => maybeThen(resolveLazy(), (fn) => {
9518
+ if (!isFunction(fn)) {
9519
+ throw qError(QError_qrlIsNotFunction);
9520
+ }
9521
+ if (beforeFn && beforeFn() === false) {
9522
+ return;
9523
+ }
9524
+ const context = createOrReuseInvocationContext(currentCtx);
9525
+ const prevQrl = context.$qrl$;
9526
+ const prevEvent = context.$event$;
9527
+ // Note that we set the qrl here instead of in wrapFn because
9528
+ // it is possible we're called on a copied qrl
9529
+ context.$qrl$ = qrl;
9530
+ context.$event$ ||= this;
9531
+ try {
9532
+ return invoke.call(this, context, fn, ...args);
9533
+ }
9534
+ finally {
9535
+ context.$qrl$ = prevQrl;
9536
+ context.$event$ = prevEvent;
9537
+ }
9538
+ });
9539
+ }
9540
+ const resolveLazy = (containerEl) => {
9541
+ return symbolRef !== null ? symbolRef : resolve(containerEl);
9542
+ };
9507
9543
  // Wrap functions to provide their lexical scope
9508
9544
  const wrapFn = (fn) => {
9509
9545
  if (typeof fn !== 'function' || (!capture?.length && !captureRef?.length)) {
@@ -9556,34 +9592,6 @@
9556
9592
  }
9557
9593
  return symbolRef;
9558
9594
  };
9559
- const resolveLazy = (containerEl) => {
9560
- return symbolRef !== null ? symbolRef : resolve(containerEl);
9561
- };
9562
- function invokeFn(currentCtx, beforeFn) {
9563
- // Note that we bind the current `this`
9564
- return (...args) => maybeThen(resolveLazy(), (f) => {
9565
- if (!isFunction(f)) {
9566
- throw qError(QError_qrlIsNotFunction);
9567
- }
9568
- if (beforeFn && beforeFn() === false) {
9569
- return;
9570
- }
9571
- const context = createOrReuseInvocationContext(currentCtx);
9572
- const prevQrl = context.$qrl$;
9573
- const prevEvent = context.$event$;
9574
- // Note that we set the qrl here instead of in wrapFn because
9575
- // it is possible we're called on a copied qrl
9576
- context.$qrl$ = qrl;
9577
- context.$event$ ||= this;
9578
- try {
9579
- return invoke.call(this, context, f, ...args);
9580
- }
9581
- finally {
9582
- context.$qrl$ = prevQrl;
9583
- context.$event$ = prevEvent;
9584
- }
9585
- });
9586
- }
9587
9595
  const createOrReuseInvocationContext = (invoke) => {
9588
9596
  if (invoke == null) {
9589
9597
  return newInvokeContext();
@@ -9608,7 +9616,7 @@
9608
9616
  $symbol$: symbol,
9609
9617
  $refSymbol$: refSymbol,
9610
9618
  $hash$: hash,
9611
- getFn: invokeFn,
9619
+ getFn: bindFnToContext,
9612
9620
  $capture$: capture,
9613
9621
  $captureRef$: captureRef,
9614
9622
  dev: null,