Skip to content

Commit fdaa937

Browse files
committed
Draft of synchronized bundle reader
1 parent 2d01a6d commit fdaa937

File tree

3 files changed

+102
-3
lines changed

3 files changed

+102
-3
lines changed

packages/firestore/src/core/firestore_client.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ async function ensureOfflineComponents(
339339
return client._offlineComponents!;
340340
}
341341

342-
async function ensureOnlineComponents(
342+
export async function ensureOnlineComponents(
343343
client: FirestoreClient
344344
): Promise<OnlineComponentProvider> {
345345
if (!client._onlineComponents) {
@@ -799,6 +799,16 @@ export function firestoreClientLoadBundle(
799799
});
800800
}
801801

802+
export function firestoreClientLoadDodcumentSnapshotBundle(
803+
client: FirestoreClient,
804+
databaseId: DatabaseId,
805+
data: string
806+
): object {
807+
const reader = createBundleReader(data, newSerializer(databaseId));
808+
const encodedContent: Uint8Array = newTextEncoder().encode(data);
809+
return {};
810+
}
811+
802812
export function firestoreClientGetNamedQuery(
803813
client: FirestoreClient,
804814
queryName: string
@@ -808,7 +818,7 @@ export function firestoreClientGetNamedQuery(
808818
);
809819
}
810820

811-
function createBundleReader(
821+
export function createBundleReader(
812822
data: ReadableStream<Uint8Array> | ArrayBuffer | string,
813823
serializer: JsonProtoSerializer
814824
): BundleReader {

packages/firestore/src/util/bundle_reader.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,11 @@ export class SizedBundleElement {
3030
public readonly payload: BundleElement,
3131
// How many bytes this element takes to store in the bundle.
3232
public readonly byteLength: number
33-
) {}
33+
) {
34+
console.log('DEDB new sizedBundle element.');
35+
console.log('payload: ', payload);
36+
console.log('byteLength: ', byteLength);
37+
}
3438

3539
isBundleMetadata(): boolean {
3640
return 'metadata' in this.payload;

packages/firestore/src/util/bundle_reader_impl.ts

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,91 @@ import { debugAssert } from './assert';
2323
import { BundleReader, SizedBundleElement } from './bundle_reader';
2424
import { Deferred } from './promise';
2525

26+
class SyncBundleReaderImpl {
27+
private metadata: BundleMetadata | null;
28+
private elements: Array<SizedBundleElement>;
29+
private cursor: number;
30+
constructor(
31+
/** The reader to read from underlying binary bundle data source. */
32+
private bundleData: string,
33+
readonly serializer: JsonProtoSerializer
34+
) {
35+
this.metadata = null;
36+
this.cursor = 0;
37+
this.elements = new Array<SizedBundleElement>();
38+
}
39+
40+
parse(): void {
41+
let element = this.nextElement();
42+
if (element && element.isBundleMetadata()) {
43+
this.metadata = element as BundleMetadata;
44+
} else {
45+
throw new Error(`The first element of the bundle is not a metadata, it is
46+
${JSON.stringify(element?.payload)}`);
47+
}
48+
}
49+
50+
getMetadata(): BundleMetadata | null {
51+
return this.metadata;
52+
}
53+
54+
private nextElement(): SizedBundleElement | null {
55+
if (this.cursor === this.bundleData.length) {
56+
return null;
57+
}
58+
59+
const length = this.readLength();
60+
const jsonString = this.readJsonString(length);
61+
62+
return new SizedBundleElement(JSON.parse(jsonString), jsonString.length);
63+
}
64+
65+
/**
66+
* Reads from a specified position from the bundleData string, for a specified
67+
* number of bytes.
68+
*
69+
* Returns a string parsed from the bundle.
70+
*/
71+
private readJsonString(length: number): string {
72+
if (this.cursor + length > this.bundleData.length) {
73+
throw new Error('Reached the end of bundle when more is expected.');
74+
}
75+
const result = this.bundleData.slice(this.cursor, length);
76+
this.cursor += length;
77+
return result;
78+
}
79+
80+
/** First index of '{' from the bundle starting at the optionally provided offset. */
81+
private indexOfOpenBracket(offset?: number): number {
82+
let buffer: string = this.bundleData;
83+
if (offset) {
84+
buffer = this.bundleData.substring(offset);
85+
}
86+
return buffer.indexOf('{');
87+
}
88+
89+
/**
90+
* Reads from the current cursor until the first '{', returns number value
91+
*
92+
* If reached end of the stream, or the value isn't a number, then throws.
93+
*/
94+
private readLength(): number {
95+
const startIndex = this.cursor;
96+
let curIndex = this.cursor;
97+
while (curIndex < this.bundleData.length) {
98+
if (this.bundleData[curIndex] === '{') {
99+
if (curIndex === startIndex) {
100+
throw new Error('First character is a bracket and not a number');
101+
}
102+
this.cursor = curIndex;
103+
return Number(this.bundleData.slice(startIndex, curIndex));
104+
}
105+
curIndex++;
106+
}
107+
throw new Error('Reached the end of bundle when more is expected.');
108+
}
109+
}
110+
26111
/**
27112
* A class representing a bundle.
28113
*

0 commit comments

Comments
 (0)