Repository: facebook/react
File: packages/react-server-dom-webpack/src/__tests__/ReactFlightDOMEdge-test.js (JavaScript)

Code before:
    expect(await iterator.next()).toEqual({value: undefined, done: true});
  });

  it('dedupes objects inside async iterables or readablestreams', async () => {
    const obj = {
      this: {is: 'a large objected'},
      with: {many: 'properties in it'},
    };
    const iterable = {
      async *[Symbol.asyncIterator]() {
        for (let i = 0; i < 30; i++) {
          yield obj;
        }
      },
    };

    const stream = ReactServerDOMServer.renderToReadableStream({
      iterable,
    });
    const [stream1, stream2] = passThrough(stream).tee();

    const serializedContent = await readResult(stream1);
    // TODO: Ideally streams should dedupe objects but because we never outline the objects
    // they end up not having a row to reference them nor any of its nested objects.
    // expect(serializedContent.length).toBeLessThan(400);

    const result = await ReactServerDOMClient.createFromReadableStream(
      stream2,
      {
        ssrManifest: {
          moduleMap: null,
          moduleLoading: null,
        },
      },
    );

    let items = [];
    const iterator = result.iterable[Symbol.asyncIterator]();
    let entry;
    while (!(entry = await iterator.next()).done) {
      items.push(entry.value);
    }

    // Should still match the result when parsed
    expect(items.length).toBe(30);
    // TODO: These should be the same
    // expect(items[5]).toBe(items[10]); // two random items are the same instance
    expect(items[5]).toEqual(items[10]);
  });

  it('warns if passing a this argument to bind() of a server reference', async () => {

Review comment (suggestion):
Add a test to show case this. This used to work by the second row getting outlined.

Because every "chunk/entry" inside a stream has the same ID we can't refer to those objects. Only the stream object itself (`ReadableStream` or `AsyncIterable`) has a row ID.

This means we can't dedupe the object at the root of a stream row. Since we don't have a reference to that object we also can't dedupe the nested object via the parent neither. Leading to duplicating all these objects.

It seems unfortunate to outline every chunk/entry in a stream just in case it needs deduping.

Code after:
    expect(await iterator.next()).toEqual({value: undefined, done: true});
  });

  // @gate enableFlightReadableStream
  it('should ideally dedupe objects inside async iterables but does not yet', async () => {
    const obj = {
      this: {is: 'a large objected'},
      with: {many: 'properties in it'},
    };
    const iterable = {
      async *[Symbol.asyncIterator]() {
        for (let i = 0; i < 30; i++) {
          yield obj;
        }
      },
    };

    const stream = ReactServerDOMServer.renderToReadableStream({
      iterable,
    });
    const [stream1, stream2] = passThrough(stream).tee();

    const serializedContent = await readResult(stream1);
    // TODO: Ideally streams should dedupe objects but because we never outline the objects
    // they end up not having a row to reference them nor any of its nested objects.
    // expect(serializedContent.length).toBeLessThan(400);
    expect(serializedContent.length).toBeGreaterThan(400);

    const result = await ReactServerDOMClient.createFromReadableStream(
      stream2,
      {
        ssrManifest: {
          moduleMap: null,
          moduleLoading: null,
        },
      },
    );

    const items = [];
    const iterator = result.iterable[Symbol.asyncIterator]();
    let entry;
    while (!(entry = await iterator.next()).done) {
      items.push(entry.value);
    }

    // Should still match the result when parsed
    expect(items.length).toBe(30);
    // TODO: These should be the same
    // expect(items[5]).toBe(items[10]); // two random items are the same instance
    expect(items[5]).toEqual(items[10]);
  });