From 1869f65c245b9fa4470aa62b6f19c013778ac7d7 Mon Sep 17 00:00:00 2001 From: milaGGL <107142260+milaGGL@users.noreply.github.com> Date: Mon, 6 Jan 2025 10:35:38 -0500 Subject: [PATCH 01/13] add a test --- packages/firestore/src/model/values.ts | 11 ++++++- .../test/integration/api/query.test.ts | 32 +++++++++++++++++-- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/packages/firestore/src/model/values.ts b/packages/firestore/src/model/values.ts index 1977767515e..4be6aa41342 100644 --- a/packages/firestore/src/model/values.ts +++ b/packages/firestore/src/model/values.ts @@ -41,6 +41,7 @@ import { isServerTimestamp } from './server_timestamps'; import { TypeOrder } from './type_order'; +import {ByteString} from "../util/byte_string"; export const TYPE_KEY = '__type__'; const MAX_VALUE_TYPE = '__max__'; @@ -251,7 +252,9 @@ export function valueCompare(left: Value, right: Value): number { getLocalWriteTime(right) ); case TypeOrder.StringValue: - return primitiveComparator(left.stringValue!, right.stringValue!); + return compareBlobs(stringValueToUint8Array(left.stringValue!),stringValueToUint8Array(right.stringValue!)) + // return compareBlobs(left.stringValue!, right.stringValue!); + // return primitiveComparator(left.stringValue!, right.stringValue!); case TypeOrder.BlobValue: return compareBlobs(left.bytesValue!, right.bytesValue!); case TypeOrder.RefValue: @@ -269,6 +272,12 @@ export function valueCompare(left: Value, right: Value): number { } } +function stringValueToUint8Array(stringValue: string): Uint8Array { + // Use TextEncoder to convert the string to UTF-8 encoded bytes + const encoder = new TextEncoder(); + return encoder.encode(stringValue); +} + function compareNumbers(left: Value, right: Value): number { const leftNumber = normalizeNumber(left.integerValue || left.doubleValue); const rightNumber = normalizeNumber(right.integerValue || right.doubleValue); diff --git a/packages/firestore/test/integration/api/query.test.ts b/packages/firestore/test/integration/api/query.test.ts index 01fd0e47e35..1548b24ab72 100644 --- a/packages/firestore/test/integration/api/query.test.ts +++ b/packages/firestore/test/integration/api/query.test.ts @@ -54,7 +54,8 @@ import { writeBatch, CollectionReference, WriteBatch, - Firestore + Firestore, + getDocsFromServer } from '../util/firebase_export'; import { apiDescribe, @@ -66,7 +67,8 @@ import { withRetry, withTestCollection, withTestDb, - checkOnlineAndOfflineResultsMatch + checkOnlineAndOfflineResultsMatch, + toIds } from '../util/helpers'; import { USE_EMULATOR } from '../util/settings'; import { captureExistenceFilterMismatches } from '../util/testing_hooks_util'; @@ -2218,6 +2220,32 @@ apiDescribe('Queries', persistence => { } ).timeout('90s'); + it.only('snapshot listener sorts cross type numbers same way as server', async () => { + const testDocs = { + 'a': { value: 'Łukasiewicz' }, + 'b': { value: 'Sierpiński' }, + 'c': { value: '岩澤' }, + 'd': { value: '🄟' }, + 'e': { value: 'P' }, + 'f': { value: '︒' }, + 'g': { value: '🐵' }, + }; + + return withTestCollection(persistence, testDocs, async collectionRef => { + const orderedQuery = query(collectionRef, orderBy('value')); + + const getSnapshot = await getDocsFromServer(orderedQuery); + expect(toIds(getSnapshot)).to.deep.equal(["b", "a", "c", "f", "e", "d", "g"]); + + const storeEvent = new EventsAccumulator(); + const unsubscribe = onSnapshot(orderedQuery, storeEvent.storeEvent); + const watchSnapshot = await storeEvent.awaitEvent(); + expect(toIds(watchSnapshot)).to.deep.equal(toIds(getSnapshot)); + + unsubscribe(); + }); + }); + it('can query large documents with multi-byte character strings', () => { function randomMultiByteCharString(length: number): string { const charCodes: number[] = []; From ca556a2be71aeb6f8f42ec3bdb2ddd3b6f5caaf9 Mon Sep 17 00:00:00 2001 From: milaGGL <107142260+milaGGL@users.noreply.github.com> Date: Mon, 6 Jan 2025 11:56:43 -0500 Subject: [PATCH 02/13] fix lint --- packages/firestore/src/model/values.ts | 1 - packages/firestore/test/integration/api/query.test.ts | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/firestore/src/model/values.ts b/packages/firestore/src/model/values.ts index 4be6aa41342..49f6306688a 100644 --- a/packages/firestore/src/model/values.ts +++ b/packages/firestore/src/model/values.ts @@ -41,7 +41,6 @@ import { isServerTimestamp } from './server_timestamps'; import { TypeOrder } from './type_order'; -import {ByteString} from "../util/byte_string"; export const TYPE_KEY = '__type__'; const MAX_VALUE_TYPE = '__max__'; diff --git a/packages/firestore/test/integration/api/query.test.ts b/packages/firestore/test/integration/api/query.test.ts index 1548b24ab72..36052ecd811 100644 --- a/packages/firestore/test/integration/api/query.test.ts +++ b/packages/firestore/test/integration/api/query.test.ts @@ -2220,7 +2220,7 @@ apiDescribe('Queries', persistence => { } ).timeout('90s'); - it.only('snapshot listener sorts cross type numbers same way as server', async () => { + it('snapshot listener sorts unicode strings the same way as server', async () => { const testDocs = { 'a': { value: 'Łukasiewicz' }, 'b': { value: 'Sierpiński' }, From 2d93fc2750b912926bb3e7dc7771b456ddf9ac6e Mon Sep 17 00:00:00 2001 From: milaGGL <107142260+milaGGL@users.noreply.github.com> Date: Tue, 7 Jan 2025 13:51:04 -0500 Subject: [PATCH 03/13] add more tests --- packages/firestore/src/model/path.ts | 9 +- packages/firestore/src/model/values.ts | 11 +- .../test/integration/api/database.test.ts | 172 ++++++++++++++++++ .../test/integration/api/query.test.ts | 32 +--- 4 files changed, 184 insertions(+), 40 deletions(-) diff --git a/packages/firestore/src/model/path.ts b/packages/firestore/src/model/path.ts index 64cb0376a0e..b98ac3b54f4 100644 --- a/packages/firestore/src/model/path.ts +++ b/packages/firestore/src/model/path.ts @@ -17,6 +17,7 @@ import { Integer } from '@firebase/webchannel-wrapper/bloom-blob'; +import { compareUtf8Strings } from '../model/values'; import { debugAssert, fail } from '../util/assert'; import { Code, FirestoreError } from '../util/error'; @@ -201,13 +202,7 @@ abstract class BasePath> { ); } else { // both non-numeric - if (lhs < rhs) { - return -1; - } - if (lhs > rhs) { - return 1; - } - return 0; + return compareUtf8Strings(lhs, rhs); } } diff --git a/packages/firestore/src/model/values.ts b/packages/firestore/src/model/values.ts index 49f6306688a..cc92232c8e0 100644 --- a/packages/firestore/src/model/values.ts +++ b/packages/firestore/src/model/values.ts @@ -251,8 +251,7 @@ export function valueCompare(left: Value, right: Value): number { getLocalWriteTime(right) ); case TypeOrder.StringValue: - return compareBlobs(stringValueToUint8Array(left.stringValue!),stringValueToUint8Array(right.stringValue!)) - // return compareBlobs(left.stringValue!, right.stringValue!); + return compareUtf8Strings(left.stringValue!, right.stringValue!); // return primitiveComparator(left.stringValue!, right.stringValue!); case TypeOrder.BlobValue: return compareBlobs(left.bytesValue!, right.bytesValue!); @@ -277,6 +276,12 @@ function stringValueToUint8Array(stringValue: string): Uint8Array { return encoder.encode(stringValue); } +export function compareUtf8Strings(left: string, right: string): number { + const leftBytes = stringValueToUint8Array(left); + const rightBytes = stringValueToUint8Array(right); + return compareBlobs(leftBytes, rightBytes); +} + function compareNumbers(left: Value, right: Value): number { const leftNumber = normalizeNumber(left.integerValue || left.doubleValue); const rightNumber = normalizeNumber(right.integerValue || right.doubleValue); @@ -408,7 +413,7 @@ function compareMaps(left: MapValue, right: MapValue): number { rightKeys.sort(); for (let i = 0; i < leftKeys.length && i < rightKeys.length; ++i) { - const keyCompare = primitiveComparator(leftKeys[i], rightKeys[i]); + const keyCompare = compareUtf8Strings(leftKeys[i], rightKeys[i]); if (keyCompare !== 0) { return keyCompare; } diff --git a/packages/firestore/test/integration/api/database.test.ts b/packages/firestore/test/integration/api/database.test.ts index 1cda49d9229..2f8a7321bb2 100644 --- a/packages/firestore/test/integration/api/database.test.ts +++ b/packages/firestore/test/integration/api/database.test.ts @@ -2424,4 +2424,176 @@ apiDescribe('Database', persistence => { }); }); }); + + describe('Unicode strings', () => { + it('snapshot listener sorts unicode strings the same as server', async () => { + const testDocs = { + 'a': { value: 'Łukasiewicz' }, + 'b': { value: 'Sierpiński' }, + 'c': { value: '岩澤' }, + 'd': { value: '🄟' }, + 'e': { value: 'P' }, + 'f': { value: '︒' }, + 'g': { value: '🐵' } + }; + + return withTestCollection(persistence, testDocs, async collectionRef => { + const orderedQuery = query(collectionRef, orderBy('value')); + + const getSnapshot = await getDocsFromServer(orderedQuery); + expect(toIds(getSnapshot)).to.deep.equal([ + 'b', + 'a', + 'c', + 'f', + 'e', + 'd', + 'g' + ]); + + const storeEvent = new EventsAccumulator(); + const unsubscribe = onSnapshot(orderedQuery, storeEvent.storeEvent); + const watchSnapshot = await storeEvent.awaitEvent(); + expect(toIds(watchSnapshot)).to.deep.equal(toIds(getSnapshot)); + + unsubscribe(); + }); + }); + + it('snapshot listener sorts unicode strings in array the same as server', async () => { + const testDocs = { + 'a': { value: ['Łukasiewicz'] }, + 'b': { value: ['Sierpiński'] }, + 'c': { value: ['岩澤'] }, + 'd': { value: ['🄟'] }, + 'e': { value: ['P'] }, + 'f': { value: ['︒'] }, + 'g': { value: ['🐵'] } + }; + + return withTestCollection(persistence, testDocs, async collectionRef => { + const orderedQuery = query(collectionRef, orderBy('value')); + + const getSnapshot = await getDocsFromServer(orderedQuery); + expect(toIds(getSnapshot)).to.deep.equal([ + 'b', + 'a', + 'c', + 'f', + 'e', + 'd', + 'g' + ]); + + const storeEvent = new EventsAccumulator(); + const unsubscribe = onSnapshot(orderedQuery, storeEvent.storeEvent); + const watchSnapshot = await storeEvent.awaitEvent(); + expect(toIds(watchSnapshot)).to.deep.equal(toIds(getSnapshot)); + + unsubscribe(); + }); + }); + + it('snapshot listener sorts unicode strings in map the same as server', async () => { + const testDocs = { + 'a': { value: { foo: 'Łukasiewicz' } }, + 'b': { value: { foo: 'Sierpiński' } }, + 'c': { value: { foo: '岩澤' } }, + 'd': { value: { foo: '🄟' } }, + 'e': { value: { foo: 'P' } }, + 'f': { value: { foo: '︒' } }, + 'g': { value: { foo: '🐵' } } + }; + + return withTestCollection(persistence, testDocs, async collectionRef => { + const orderedQuery = query(collectionRef, orderBy('value')); + + const getSnapshot = await getDocsFromServer(orderedQuery); + expect(toIds(getSnapshot)).to.deep.equal([ + 'b', + 'a', + 'c', + 'f', + 'e', + 'd', + 'g' + ]); + + const storeEvent = new EventsAccumulator(); + const unsubscribe = onSnapshot(orderedQuery, storeEvent.storeEvent); + const watchSnapshot = await storeEvent.awaitEvent(); + expect(toIds(watchSnapshot)).to.deep.equal(toIds(getSnapshot)); + + unsubscribe(); + }); + }); + + it('snapshot listener sorts unicode strings in map key the same as server', async () => { + const testDocs = { + 'a': { value: { 'Łukasiewicz': true } }, + 'b': { value: { 'Sierpiński': true } }, + 'c': { value: { '岩澤': true } }, + 'd': { value: { '🄟': true } }, + 'e': { value: { 'P': true } }, + 'f': { value: { '︒': true } }, + 'g': { value: { '🐵': true } } + }; + + return withTestCollection(persistence, testDocs, async collectionRef => { + const orderedQuery = query(collectionRef, orderBy('value')); + + const getSnapshot = await getDocsFromServer(orderedQuery); + expect(toIds(getSnapshot)).to.deep.equal([ + 'b', + 'a', + 'c', + 'f', + 'e', + 'd', + 'g' + ]); + + const storeEvent = new EventsAccumulator(); + const unsubscribe = onSnapshot(orderedQuery, storeEvent.storeEvent); + const watchSnapshot = await storeEvent.awaitEvent(); + expect(toIds(watchSnapshot)).to.deep.equal(toIds(getSnapshot)); + + unsubscribe(); + }); + }); + + // it('snapshot listener sorts unicode strings in document key the same as server', async () => { + // const testDocs = { + // 'Łukasiewicz': { value: true }, + // 'Sierpiński': { value: true }, + // '岩澤': { value: true }, + // '🄟': { value: true }, + // 'P': { value: true }, + // '︒': { value: true }, + // '🐵': { value: true } + // }; + // + // return withTestCollection(persistence, testDocs, async collectionRef => { + // const orderedQuery = query(collectionRef, orderBy('value')); + // + // const getSnapshot = await getDocsFromServer(orderedQuery); + // expect(toIds(getSnapshot)).to.deep.equal([ + // 'Sierpiński', + // 'Łukasiewicz', + // '岩澤', + // '︒', + // 'P', + // '🄟', + // '🐵' + // ]); + // + // const storeEvent = new EventsAccumulator(); + // const unsubscribe = onSnapshot(orderedQuery, storeEvent.storeEvent); + // const watchSnapshot = await storeEvent.awaitEvent(); + // expect(toIds(watchSnapshot)).to.deep.equal(toIds(getSnapshot)); + // + // unsubscribe(); + // }); + // }); + }); }); diff --git a/packages/firestore/test/integration/api/query.test.ts b/packages/firestore/test/integration/api/query.test.ts index 36052ecd811..01fd0e47e35 100644 --- a/packages/firestore/test/integration/api/query.test.ts +++ b/packages/firestore/test/integration/api/query.test.ts @@ -54,8 +54,7 @@ import { writeBatch, CollectionReference, WriteBatch, - Firestore, - getDocsFromServer + Firestore } from '../util/firebase_export'; import { apiDescribe, @@ -67,8 +66,7 @@ import { withRetry, withTestCollection, withTestDb, - checkOnlineAndOfflineResultsMatch, - toIds + checkOnlineAndOfflineResultsMatch } from '../util/helpers'; import { USE_EMULATOR } from '../util/settings'; import { captureExistenceFilterMismatches } from '../util/testing_hooks_util'; @@ -2220,32 +2218,6 @@ apiDescribe('Queries', persistence => { } ).timeout('90s'); - it('snapshot listener sorts unicode strings the same way as server', async () => { - const testDocs = { - 'a': { value: 'Łukasiewicz' }, - 'b': { value: 'Sierpiński' }, - 'c': { value: '岩澤' }, - 'd': { value: '🄟' }, - 'e': { value: 'P' }, - 'f': { value: '︒' }, - 'g': { value: '🐵' }, - }; - - return withTestCollection(persistence, testDocs, async collectionRef => { - const orderedQuery = query(collectionRef, orderBy('value')); - - const getSnapshot = await getDocsFromServer(orderedQuery); - expect(toIds(getSnapshot)).to.deep.equal(["b", "a", "c", "f", "e", "d", "g"]); - - const storeEvent = new EventsAccumulator(); - const unsubscribe = onSnapshot(orderedQuery, storeEvent.storeEvent); - const watchSnapshot = await storeEvent.awaitEvent(); - expect(toIds(watchSnapshot)).to.deep.equal(toIds(getSnapshot)); - - unsubscribe(); - }); - }); - it('can query large documents with multi-byte character strings', () => { function randomMultiByteCharString(length: number): string { const charCodes: number[] = []; From 7ce17110ea7e5d77caca7cffe9e123e42fa2bef0 Mon Sep 17 00:00:00 2001 From: milaGGL <107142260+milaGGL@users.noreply.github.com> Date: Wed, 8 Jan 2025 14:11:19 -0500 Subject: [PATCH 04/13] fix circular dependency --- docs-devsite/_toc.yaml | 126 +++++++--------- docs-devsite/index.md | 2 +- docs-devsite/vertexai-preview.baseparams.md | 42 ++++++ docs-devsite/vertexai-preview.chatsession.md | 138 ++++++++++++++++++ docs-devsite/vertexai-preview.citation.md | 78 ++++++++++ .../vertexai-preview.citationmetadata.md | 33 +++++ docs-devsite/vertexai-preview.content.md | 42 ++++++ .../vertexai-preview.counttokensrequest.md | 33 +++++ .../vertexai-preview.counttokensresponse.md | 46 ++++++ docs-devsite/vertexai-preview.date_2.md | 51 +++++++ ...preview.enhancedgeneratecontentresponse.md | 45 ++++++ packages/firestore/src/model/comparator.ts | 39 +++++ packages/firestore/src/model/path.ts | 3 +- packages/firestore/src/model/values.ts | 22 +-- .../test/integration/api/database.test.ts | 66 ++++----- 15 files changed, 634 insertions(+), 132 deletions(-) create mode 100644 docs-devsite/vertexai-preview.baseparams.md create mode 100644 docs-devsite/vertexai-preview.chatsession.md create mode 100644 docs-devsite/vertexai-preview.citation.md create mode 100644 docs-devsite/vertexai-preview.citationmetadata.md create mode 100644 docs-devsite/vertexai-preview.content.md create mode 100644 docs-devsite/vertexai-preview.counttokensrequest.md create mode 100644 docs-devsite/vertexai-preview.counttokensresponse.md create mode 100644 docs-devsite/vertexai-preview.date_2.md create mode 100644 docs-devsite/vertexai-preview.enhancedgeneratecontentresponse.md create mode 100644 packages/firestore/src/model/comparator.ts diff --git a/docs-devsite/_toc.yaml b/docs-devsite/_toc.yaml index ca06d4f9398..a8217a15f6b 100644 --- a/docs-devsite/_toc.yaml +++ b/docs-devsite/_toc.yaml @@ -461,124 +461,98 @@ toc: path: /docs/reference/js/storage.uploadtask.md - title: UploadTaskSnapshot path: /docs/reference/js/storage.uploadtasksnapshot.md -- title: vertexai - path: /docs/reference/js/vertexai.md +- title: vertexai-preview + path: /docs/reference/js/vertexai-preview.md section: - - title: ArraySchema - path: /docs/reference/js/vertexai.arrayschema.md - title: BaseParams - path: /docs/reference/js/vertexai.baseparams.md - - title: BooleanSchema - path: /docs/reference/js/vertexai.booleanschema.md + path: /docs/reference/js/vertexai-preview.baseparams.md - title: ChatSession - path: /docs/reference/js/vertexai.chatsession.md + path: /docs/reference/js/vertexai-preview.chatsession.md - title: Citation - path: /docs/reference/js/vertexai.citation.md + path: /docs/reference/js/vertexai-preview.citation.md - title: CitationMetadata - path: /docs/reference/js/vertexai.citationmetadata.md + path: /docs/reference/js/vertexai-preview.citationmetadata.md - title: Content - path: /docs/reference/js/vertexai.content.md + path: /docs/reference/js/vertexai-preview.content.md - title: CountTokensRequest - path: /docs/reference/js/vertexai.counttokensrequest.md + path: /docs/reference/js/vertexai-preview.counttokensrequest.md - title: CountTokensResponse - path: /docs/reference/js/vertexai.counttokensresponse.md - - title: CustomErrorData - path: /docs/reference/js/vertexai.customerrordata.md + path: /docs/reference/js/vertexai-preview.counttokensresponse.md - title: Date_2 - path: /docs/reference/js/vertexai.date_2.md + path: /docs/reference/js/vertexai-preview.date_2.md - title: EnhancedGenerateContentResponse - path: /docs/reference/js/vertexai.enhancedgeneratecontentresponse.md - - title: ErrorDetails - path: /docs/reference/js/vertexai.errordetails.md + path: /docs/reference/js/vertexai-preview.enhancedgeneratecontentresponse.md - title: FileData - path: /docs/reference/js/vertexai.filedata.md + path: /docs/reference/js/vertexai-preview.filedata.md - title: FileDataPart - path: /docs/reference/js/vertexai.filedatapart.md + path: /docs/reference/js/vertexai-preview.filedatapart.md - title: FunctionCall - path: /docs/reference/js/vertexai.functioncall.md + path: /docs/reference/js/vertexai-preview.functioncall.md - title: FunctionCallingConfig - path: /docs/reference/js/vertexai.functioncallingconfig.md + path: /docs/reference/js/vertexai-preview.functioncallingconfig.md - title: FunctionCallPart - path: /docs/reference/js/vertexai.functioncallpart.md + path: /docs/reference/js/vertexai-preview.functioncallpart.md - title: FunctionDeclaration - path: /docs/reference/js/vertexai.functiondeclaration.md + path: /docs/reference/js/vertexai-preview.functiondeclaration.md + - title: FunctionDeclarationSchema + path: /docs/reference/js/vertexai-preview.functiondeclarationschema.md + - title: FunctionDeclarationSchemaProperty + path: /docs/reference/js/vertexai-preview.functiondeclarationschemaproperty.md - title: FunctionDeclarationsTool - path: /docs/reference/js/vertexai.functiondeclarationstool.md + path: /docs/reference/js/vertexai-preview.functiondeclarationstool.md - title: FunctionResponse - path: /docs/reference/js/vertexai.functionresponse.md + path: /docs/reference/js/vertexai-preview.functionresponse.md - title: FunctionResponsePart - path: /docs/reference/js/vertexai.functionresponsepart.md + path: /docs/reference/js/vertexai-preview.functionresponsepart.md - title: GenerateContentCandidate - path: /docs/reference/js/vertexai.generatecontentcandidate.md + path: /docs/reference/js/vertexai-preview.generatecontentcandidate.md - title: GenerateContentRequest - path: /docs/reference/js/vertexai.generatecontentrequest.md + path: /docs/reference/js/vertexai-preview.generatecontentrequest.md - title: GenerateContentResponse - path: /docs/reference/js/vertexai.generatecontentresponse.md + path: /docs/reference/js/vertexai-preview.generatecontentresponse.md - title: GenerateContentResult - path: /docs/reference/js/vertexai.generatecontentresult.md + path: /docs/reference/js/vertexai-preview.generatecontentresult.md - title: GenerateContentStreamResult - path: /docs/reference/js/vertexai.generatecontentstreamresult.md + path: /docs/reference/js/vertexai-preview.generatecontentstreamresult.md - title: GenerationConfig - path: /docs/reference/js/vertexai.generationconfig.md + path: /docs/reference/js/vertexai-preview.generationconfig.md - title: GenerativeContentBlob - path: /docs/reference/js/vertexai.generativecontentblob.md + path: /docs/reference/js/vertexai-preview.generativecontentblob.md - title: GenerativeModel - path: /docs/reference/js/vertexai.generativemodel.md + path: /docs/reference/js/vertexai-preview.generativemodel.md - title: GroundingAttribution - path: /docs/reference/js/vertexai.groundingattribution.md + path: /docs/reference/js/vertexai-preview.groundingattribution.md - title: GroundingMetadata - path: /docs/reference/js/vertexai.groundingmetadata.md + path: /docs/reference/js/vertexai-preview.groundingmetadata.md - title: InlineDataPart - path: /docs/reference/js/vertexai.inlinedatapart.md - - title: IntegerSchema - path: /docs/reference/js/vertexai.integerschema.md + path: /docs/reference/js/vertexai-preview.inlinedatapart.md - title: ModelParams - path: /docs/reference/js/vertexai.modelparams.md - - title: NumberSchema - path: /docs/reference/js/vertexai.numberschema.md - - title: ObjectSchema - path: /docs/reference/js/vertexai.objectschema.md - - title: ObjectSchemaInterface - path: /docs/reference/js/vertexai.objectschemainterface.md + path: /docs/reference/js/vertexai-preview.modelparams.md - title: PromptFeedback - path: /docs/reference/js/vertexai.promptfeedback.md + path: /docs/reference/js/vertexai-preview.promptfeedback.md - title: RequestOptions - path: /docs/reference/js/vertexai.requestoptions.md + path: /docs/reference/js/vertexai-preview.requestoptions.md - title: RetrievedContextAttribution - path: /docs/reference/js/vertexai.retrievedcontextattribution.md + path: /docs/reference/js/vertexai-preview.retrievedcontextattribution.md - title: SafetyRating - path: /docs/reference/js/vertexai.safetyrating.md + path: /docs/reference/js/vertexai-preview.safetyrating.md - title: SafetySetting - path: /docs/reference/js/vertexai.safetysetting.md - - title: Schema - path: /docs/reference/js/vertexai.schema.md - - title: SchemaInterface - path: /docs/reference/js/vertexai.schemainterface.md - - title: SchemaParams - path: /docs/reference/js/vertexai.schemaparams.md - - title: SchemaRequest - path: /docs/reference/js/vertexai.schemarequest.md - - title: SchemaShared - path: /docs/reference/js/vertexai.schemashared.md + path: /docs/reference/js/vertexai-preview.safetysetting.md - title: Segment - path: /docs/reference/js/vertexai.segment.md + path: /docs/reference/js/vertexai-preview.segment.md - title: StartChatParams - path: /docs/reference/js/vertexai.startchatparams.md - - title: StringSchema - path: /docs/reference/js/vertexai.stringschema.md + path: /docs/reference/js/vertexai-preview.startchatparams.md - title: TextPart - path: /docs/reference/js/vertexai.textpart.md + path: /docs/reference/js/vertexai-preview.textpart.md - title: ToolConfig - path: /docs/reference/js/vertexai.toolconfig.md + path: /docs/reference/js/vertexai-preview.toolconfig.md - title: UsageMetadata - path: /docs/reference/js/vertexai.usagemetadata.md + path: /docs/reference/js/vertexai-preview.usagemetadata.md - title: VertexAI - path: /docs/reference/js/vertexai.vertexai.md - - title: VertexAIError - path: /docs/reference/js/vertexai.vertexaierror.md + path: /docs/reference/js/vertexai-preview.vertexai.md - title: VertexAIOptions - path: /docs/reference/js/vertexai.vertexaioptions.md + path: /docs/reference/js/vertexai-preview.vertexaioptions.md - title: VideoMetadata - path: /docs/reference/js/vertexai.videometadata.md + path: /docs/reference/js/vertexai-preview.videometadata.md - title: WebAttribution - path: /docs/reference/js/vertexai.webattribution.md + path: /docs/reference/js/vertexai-preview.webattribution.md diff --git a/docs-devsite/index.md b/docs-devsite/index.md index 82fdb36f076..2c22b58d80c 100644 --- a/docs-devsite/index.md +++ b/docs-devsite/index.md @@ -27,5 +27,5 @@ https://github.com/firebase/firebase-js-sdk | [@firebase/performance](./performance.md#performance_package) | The Firebase Performance Monitoring Web SDK. This SDK does not work in a Node.js environment. | | [@firebase/remote-config](./remote-config.md#remote-config_package) | The Firebase Remote Config Web SDK. This SDK does not work in a Node.js environment. | | [@firebase/storage](./storage.md#storage_package) | Cloud Storage for Firebase | -| [@firebase/vertexai](./vertexai.md#vertexai_package) | The Vertex AI in Firebase Web SDK. | +| [@firebase/vertexai-preview](./vertexai-preview.md#vertexai-preview_package) | The Vertex AI For Firebase Web SDK. | diff --git a/docs-devsite/vertexai-preview.baseparams.md b/docs-devsite/vertexai-preview.baseparams.md new file mode 100644 index 00000000000..6756c919ccc --- /dev/null +++ b/docs-devsite/vertexai-preview.baseparams.md @@ -0,0 +1,42 @@ +Project: /docs/reference/js/_project.yaml +Book: /docs/reference/_book.yaml +page_type: reference + +{% comment %} +DO NOT EDIT THIS FILE! +This is generated by the JS SDK team, and any local changes will be +overwritten. Changes should be made in the source code at +https://github.com/firebase/firebase-js-sdk +{% endcomment %} + +# BaseParams interface +Base parameters for a number of methods. + +Signature: + +```typescript +export interface BaseParams +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [generationConfig](./vertexai-preview.baseparams.md#baseparamsgenerationconfig) | [GenerationConfig](./vertexai-preview.generationconfig.md#generationconfig_interface) | | +| [safetySettings](./vertexai-preview.baseparams.md#baseparamssafetysettings) | [SafetySetting](./vertexai-preview.safetysetting.md#safetysetting_interface)\[\] | | + +## BaseParams.generationConfig + +Signature: + +```typescript +generationConfig?: GenerationConfig; +``` + +## BaseParams.safetySettings + +Signature: + +```typescript +safetySettings?: SafetySetting[]; +``` diff --git a/docs-devsite/vertexai-preview.chatsession.md b/docs-devsite/vertexai-preview.chatsession.md new file mode 100644 index 00000000000..3d78bab3745 --- /dev/null +++ b/docs-devsite/vertexai-preview.chatsession.md @@ -0,0 +1,138 @@ +Project: /docs/reference/js/_project.yaml +Book: /docs/reference/_book.yaml +page_type: reference + +{% comment %} +DO NOT EDIT THIS FILE! +This is generated by the JS SDK team, and any local changes will be +overwritten. Changes should be made in the source code at +https://github.com/firebase/firebase-js-sdk +{% endcomment %} + +# ChatSession class +ChatSession class that enables sending chat messages and stores history of sent and received messages so far. + +Signature: + +```typescript +export declare class ChatSession +``` + +## Constructors + +| Constructor | Modifiers | Description | +| --- | --- | --- | +| [(constructor)(apiSettings, model, params, requestOptions)](./vertexai-preview.chatsession.md#chatsessionconstructor) | | Constructs a new instance of the ChatSession class | + +## Properties + +| Property | Modifiers | Type | Description | +| --- | --- | --- | --- | +| [model](./vertexai-preview.chatsession.md#chatsessionmodel) | | string | | +| [params](./vertexai-preview.chatsession.md#chatsessionparams) | | [StartChatParams](./vertexai-preview.startchatparams.md#startchatparams_interface) \| undefined | | +| [requestOptions](./vertexai-preview.chatsession.md#chatsessionrequestoptions) | | [RequestOptions](./vertexai-preview.requestoptions.md#requestoptions_interface) \| undefined | | + +## Methods + +| Method | Modifiers | Description | +| --- | --- | --- | +| [getHistory()](./vertexai-preview.chatsession.md#chatsessiongethistory) | | Gets the chat history so far. Blocked prompts are not added to history. Blocked candidates are not added to history, nor are the prompts that generated them. | +| [sendMessage(request)](./vertexai-preview.chatsession.md#chatsessionsendmessage) | | Sends a chat message and receives a non-streaming [GenerateContentResult](./vertexai-preview.generatecontentresult.md#generatecontentresult_interface) | +| [sendMessageStream(request)](./vertexai-preview.chatsession.md#chatsessionsendmessagestream) | | Sends a chat message and receives the response as a [GenerateContentStreamResult](./vertexai-preview.generatecontentstreamresult.md#generatecontentstreamresult_interface) containing an iterable stream and a response promise. | + +## ChatSession.(constructor) + +Constructs a new instance of the `ChatSession` class + +Signature: + +```typescript +constructor(apiSettings: ApiSettings, model: string, params?: StartChatParams | undefined, requestOptions?: RequestOptions | undefined); +``` + +#### Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| apiSettings | ApiSettings | | +| model | string | | +| params | [StartChatParams](./vertexai-preview.startchatparams.md#startchatparams_interface) \| undefined | | +| requestOptions | [RequestOptions](./vertexai-preview.requestoptions.md#requestoptions_interface) \| undefined | | + +## ChatSession.model + +Signature: + +```typescript +model: string; +``` + +## ChatSession.params + +Signature: + +```typescript +params?: StartChatParams | undefined; +``` + +## ChatSession.requestOptions + +Signature: + +```typescript +requestOptions?: RequestOptions | undefined; +``` + +## ChatSession.getHistory() + +Gets the chat history so far. Blocked prompts are not added to history. Blocked candidates are not added to history, nor are the prompts that generated them. + +Signature: + +```typescript +getHistory(): Promise; +``` +Returns: + +Promise<[Content](./vertexai-preview.content.md#content_interface)\[\]> + +## ChatSession.sendMessage() + +Sends a chat message and receives a non-streaming [GenerateContentResult](./vertexai-preview.generatecontentresult.md#generatecontentresult_interface) + +Signature: + +```typescript +sendMessage(request: string | Array): Promise; +``` + +#### Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| request | string \| Array<string \| [Part](./vertexai-preview.md#part)> | | + +Returns: + +Promise<[GenerateContentResult](./vertexai-preview.generatecontentresult.md#generatecontentresult_interface)> + +## ChatSession.sendMessageStream() + +Sends a chat message and receives the response as a [GenerateContentStreamResult](./vertexai-preview.generatecontentstreamresult.md#generatecontentstreamresult_interface) containing an iterable stream and a response promise. + +Signature: + +```typescript +sendMessageStream(request: string | Array): Promise; +``` + +#### Parameters + +| Parameter | Type | Description | +| --- | --- | --- | +| request | string \| Array<string \| [Part](./vertexai-preview.md#part)> | | + +Returns: + +Promise<[GenerateContentStreamResult](./vertexai-preview.generatecontentstreamresult.md#generatecontentstreamresult_interface)> + diff --git a/docs-devsite/vertexai-preview.citation.md b/docs-devsite/vertexai-preview.citation.md new file mode 100644 index 00000000000..10a615ee247 --- /dev/null +++ b/docs-devsite/vertexai-preview.citation.md @@ -0,0 +1,78 @@ +Project: /docs/reference/js/_project.yaml +Book: /docs/reference/_book.yaml +page_type: reference + +{% comment %} +DO NOT EDIT THIS FILE! +This is generated by the JS SDK team, and any local changes will be +overwritten. Changes should be made in the source code at +https://github.com/firebase/firebase-js-sdk +{% endcomment %} + +# Citation interface +A single citation. + +Signature: + +```typescript +export interface Citation +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [endIndex](./vertexai-preview.citation.md#citationendindex) | number | | +| [license](./vertexai-preview.citation.md#citationlicense) | string | | +| [publicationDate](./vertexai-preview.citation.md#citationpublicationdate) | Date | | +| [startIndex](./vertexai-preview.citation.md#citationstartindex) | number | | +| [title](./vertexai-preview.citation.md#citationtitle) | string | | +| [uri](./vertexai-preview.citation.md#citationuri) | string | | + +## Citation.endIndex + +Signature: + +```typescript +endIndex?: number; +``` + +## Citation.license + +Signature: + +```typescript +license?: string; +``` + +## Citation.publicationDate + +Signature: + +```typescript +publicationDate?: Date; +``` + +## Citation.startIndex + +Signature: + +```typescript +startIndex?: number; +``` + +## Citation.title + +Signature: + +```typescript +title?: string; +``` + +## Citation.uri + +Signature: + +```typescript +uri?: string; +``` diff --git a/docs-devsite/vertexai-preview.citationmetadata.md b/docs-devsite/vertexai-preview.citationmetadata.md new file mode 100644 index 00000000000..fa740ca1af7 --- /dev/null +++ b/docs-devsite/vertexai-preview.citationmetadata.md @@ -0,0 +1,33 @@ +Project: /docs/reference/js/_project.yaml +Book: /docs/reference/_book.yaml +page_type: reference + +{% comment %} +DO NOT EDIT THIS FILE! +This is generated by the JS SDK team, and any local changes will be +overwritten. Changes should be made in the source code at +https://github.com/firebase/firebase-js-sdk +{% endcomment %} + +# CitationMetadata interface +Citation metadata that may be found on a [GenerateContentCandidate](./vertexai-preview.generatecontentcandidate.md#generatecontentcandidate_interface). + +Signature: + +```typescript +export interface CitationMetadata +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [citations](./vertexai-preview.citationmetadata.md#citationmetadatacitations) | [Citation](./vertexai-preview.citation.md#citation_interface)\[\] | | + +## CitationMetadata.citations + +Signature: + +```typescript +citations: Citation[]; +``` diff --git a/docs-devsite/vertexai-preview.content.md b/docs-devsite/vertexai-preview.content.md new file mode 100644 index 00000000000..26198a3951f --- /dev/null +++ b/docs-devsite/vertexai-preview.content.md @@ -0,0 +1,42 @@ +Project: /docs/reference/js/_project.yaml +Book: /docs/reference/_book.yaml +page_type: reference + +{% comment %} +DO NOT EDIT THIS FILE! +This is generated by the JS SDK team, and any local changes will be +overwritten. Changes should be made in the source code at +https://github.com/firebase/firebase-js-sdk +{% endcomment %} + +# Content interface +Content type for both prompts and response candidates. + +Signature: + +```typescript +export interface Content +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [parts](./vertexai-preview.content.md#contentparts) | [Part](./vertexai-preview.md#part)\[\] | | +| [role](./vertexai-preview.content.md#contentrole) | [Role](./vertexai-preview.md#role) | | + +## Content.parts + +Signature: + +```typescript +parts: Part[]; +``` + +## Content.role + +Signature: + +```typescript +role: Role; +``` diff --git a/docs-devsite/vertexai-preview.counttokensrequest.md b/docs-devsite/vertexai-preview.counttokensrequest.md new file mode 100644 index 00000000000..07e5f0d85f3 --- /dev/null +++ b/docs-devsite/vertexai-preview.counttokensrequest.md @@ -0,0 +1,33 @@ +Project: /docs/reference/js/_project.yaml +Book: /docs/reference/_book.yaml +page_type: reference + +{% comment %} +DO NOT EDIT THIS FILE! +This is generated by the JS SDK team, and any local changes will be +overwritten. Changes should be made in the source code at +https://github.com/firebase/firebase-js-sdk +{% endcomment %} + +# CountTokensRequest interface +Params for calling [GenerativeModel.countTokens()](./vertexai-preview.generativemodel.md#generativemodelcounttokens) + +Signature: + +```typescript +export interface CountTokensRequest +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [contents](./vertexai-preview.counttokensrequest.md#counttokensrequestcontents) | [Content](./vertexai-preview.content.md#content_interface)\[\] | | + +## CountTokensRequest.contents + +Signature: + +```typescript +contents: Content[]; +``` diff --git a/docs-devsite/vertexai-preview.counttokensresponse.md b/docs-devsite/vertexai-preview.counttokensresponse.md new file mode 100644 index 00000000000..d097d5aacff --- /dev/null +++ b/docs-devsite/vertexai-preview.counttokensresponse.md @@ -0,0 +1,46 @@ +Project: /docs/reference/js/_project.yaml +Book: /docs/reference/_book.yaml +page_type: reference + +{% comment %} +DO NOT EDIT THIS FILE! +This is generated by the JS SDK team, and any local changes will be +overwritten. Changes should be made in the source code at +https://github.com/firebase/firebase-js-sdk +{% endcomment %} + +# CountTokensResponse interface +Response from calling [GenerativeModel.countTokens()](./vertexai-preview.generativemodel.md#generativemodelcounttokens). + +Signature: + +```typescript +export interface CountTokensResponse +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [totalBillableCharacters](./vertexai-preview.counttokensresponse.md#counttokensresponsetotalbillablecharacters) | number | The total number of billable characters counted across all instances from the request. | +| [totalTokens](./vertexai-preview.counttokensresponse.md#counttokensresponsetotaltokens) | number | The total number of tokens counted across all instances from the request. | + +## CountTokensResponse.totalBillableCharacters + +The total number of billable characters counted across all instances from the request. + +Signature: + +```typescript +totalBillableCharacters?: number; +``` + +## CountTokensResponse.totalTokens + +The total number of tokens counted across all instances from the request. + +Signature: + +```typescript +totalTokens: number; +``` diff --git a/docs-devsite/vertexai-preview.date_2.md b/docs-devsite/vertexai-preview.date_2.md new file mode 100644 index 00000000000..5af031447c4 --- /dev/null +++ b/docs-devsite/vertexai-preview.date_2.md @@ -0,0 +1,51 @@ +Project: /docs/reference/js/_project.yaml +Book: /docs/reference/_book.yaml +page_type: reference + +{% comment %} +DO NOT EDIT THIS FILE! +This is generated by the JS SDK team, and any local changes will be +overwritten. Changes should be made in the source code at +https://github.com/firebase/firebase-js-sdk +{% endcomment %} + +# Date_2 interface +Protobuf google.type.Date + +Signature: + +```typescript +export interface Date +``` + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [day](./vertexai-preview.date_2.md#date_2day) | number | | +| [month](./vertexai-preview.date_2.md#date_2month) | number | | +| [year](./vertexai-preview.date_2.md#date_2year) | number | | + +## Date\_2.day + +Signature: + +```typescript +day: number; +``` + +## Date\_2.month + +Signature: + +```typescript +month: number; +``` + +## Date\_2.year + +Signature: + +```typescript +year: number; +``` diff --git a/docs-devsite/vertexai-preview.enhancedgeneratecontentresponse.md b/docs-devsite/vertexai-preview.enhancedgeneratecontentresponse.md new file mode 100644 index 00000000000..132c5ed0be2 --- /dev/null +++ b/docs-devsite/vertexai-preview.enhancedgeneratecontentresponse.md @@ -0,0 +1,45 @@ +Project: /docs/reference/js/_project.yaml +Book: /docs/reference/_book.yaml +page_type: reference + +{% comment %} +DO NOT EDIT THIS FILE! +This is generated by the JS SDK team, and any local changes will be +overwritten. Changes should be made in the source code at +https://github.com/firebase/firebase-js-sdk +{% endcomment %} + +# EnhancedGenerateContentResponse interface +Response object wrapped with helper methods. + +Signature: + +```typescript +export interface EnhancedGenerateContentResponse extends GenerateContentResponse +``` +Extends: [GenerateContentResponse](./vertexai-preview.generatecontentresponse.md#generatecontentresponse_interface) + +## Properties + +| Property | Type | Description | +| --- | --- | --- | +| [functionCalls](./vertexai-preview.enhancedgeneratecontentresponse.md#enhancedgeneratecontentresponsefunctioncalls) | () => [FunctionCall](./vertexai-preview.functioncall.md#functioncall_interface)\[\] \| undefined | | +| [text](./vertexai-preview.enhancedgeneratecontentresponse.md#enhancedgeneratecontentresponsetext) | () => string | Returns the text string from the response, if available. Throws if the prompt or candidate was blocked. | + +## EnhancedGenerateContentResponse.functionCalls + +Signature: + +```typescript +functionCalls: () => FunctionCall[] | undefined; +``` + +## EnhancedGenerateContentResponse.text + +Returns the text string from the response, if available. Throws if the prompt or candidate was blocked. + +Signature: + +```typescript +text: () => string; +``` diff --git a/packages/firestore/src/model/comparator.ts b/packages/firestore/src/model/comparator.ts new file mode 100644 index 00000000000..e4a0b01fa5c --- /dev/null +++ b/packages/firestore/src/model/comparator.ts @@ -0,0 +1,39 @@ +/** + * @license + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { normalizeByteString } from './normalize'; + +function stringValueToUint8Array(stringValue: string): Uint8Array { + // Use TextEncoder to convert the string to UTF-8 encoded bytes + const encoder = new TextEncoder(); + return encoder.encode(stringValue); +} + +export function compareUtf8Strings(left: string, right: string): number { + const leftBytes = stringValueToUint8Array(left); + const rightBytes = stringValueToUint8Array(right); + return compareBlobs(leftBytes, rightBytes); +} + +export function compareBlobs( + left: string | Uint8Array, + right: string | Uint8Array +): number { + const leftBytes = normalizeByteString(left); + const rightBytes = normalizeByteString(right); + return leftBytes.compareTo(rightBytes); +} diff --git a/packages/firestore/src/model/path.ts b/packages/firestore/src/model/path.ts index b98ac3b54f4..2225b966c0f 100644 --- a/packages/firestore/src/model/path.ts +++ b/packages/firestore/src/model/path.ts @@ -17,10 +17,11 @@ import { Integer } from '@firebase/webchannel-wrapper/bloom-blob'; -import { compareUtf8Strings } from '../model/values'; import { debugAssert, fail } from '../util/assert'; import { Code, FirestoreError } from '../util/error'; +import { compareUtf8Strings } from './comparator'; + export const DOCUMENT_KEY_NAME = '__name__'; /** diff --git a/packages/firestore/src/model/values.ts b/packages/firestore/src/model/values.ts index cc92232c8e0..778e9ca582b 100644 --- a/packages/firestore/src/model/values.ts +++ b/packages/firestore/src/model/values.ts @@ -29,6 +29,7 @@ import { arrayEquals, primitiveComparator } from '../util/misc'; import { forEach, objectSize } from '../util/obj'; import { isNegativeZero } from '../util/types'; +import { compareBlobs, compareUtf8Strings } from './comparator'; import { DocumentKey } from './document_key'; import { normalizeByteString, @@ -270,18 +271,6 @@ export function valueCompare(left: Value, right: Value): number { } } -function stringValueToUint8Array(stringValue: string): Uint8Array { - // Use TextEncoder to convert the string to UTF-8 encoded bytes - const encoder = new TextEncoder(); - return encoder.encode(stringValue); -} - -export function compareUtf8Strings(left: string, right: string): number { - const leftBytes = stringValueToUint8Array(left); - const rightBytes = stringValueToUint8Array(right); - return compareBlobs(leftBytes, rightBytes); -} - function compareNumbers(left: Value, right: Value): number { const leftNumber = normalizeNumber(left.integerValue || left.doubleValue); const rightNumber = normalizeNumber(right.integerValue || right.doubleValue); @@ -350,15 +339,6 @@ function compareGeoPoints(left: LatLng, right: LatLng): number { ); } -function compareBlobs( - left: string | Uint8Array, - right: string | Uint8Array -): number { - const leftBytes = normalizeByteString(left); - const rightBytes = normalizeByteString(right); - return leftBytes.compareTo(rightBytes); -} - function compareArrays(left: ArrayValue, right: ArrayValue): number { const leftArray = left.values || []; const rightArray = right.values || []; diff --git a/packages/firestore/test/integration/api/database.test.ts b/packages/firestore/test/integration/api/database.test.ts index 2f8a7321bb2..1464a5c46ef 100644 --- a/packages/firestore/test/integration/api/database.test.ts +++ b/packages/firestore/test/integration/api/database.test.ts @@ -2562,38 +2562,38 @@ apiDescribe('Database', persistence => { }); }); - // it('snapshot listener sorts unicode strings in document key the same as server', async () => { - // const testDocs = { - // 'Łukasiewicz': { value: true }, - // 'Sierpiński': { value: true }, - // '岩澤': { value: true }, - // '🄟': { value: true }, - // 'P': { value: true }, - // '︒': { value: true }, - // '🐵': { value: true } - // }; - // - // return withTestCollection(persistence, testDocs, async collectionRef => { - // const orderedQuery = query(collectionRef, orderBy('value')); - // - // const getSnapshot = await getDocsFromServer(orderedQuery); - // expect(toIds(getSnapshot)).to.deep.equal([ - // 'Sierpiński', - // 'Łukasiewicz', - // '岩澤', - // '︒', - // 'P', - // '🄟', - // '🐵' - // ]); - // - // const storeEvent = new EventsAccumulator(); - // const unsubscribe = onSnapshot(orderedQuery, storeEvent.storeEvent); - // const watchSnapshot = await storeEvent.awaitEvent(); - // expect(toIds(watchSnapshot)).to.deep.equal(toIds(getSnapshot)); - // - // unsubscribe(); - // }); - // }); + it('snapshot listener sorts unicode strings in document key the same as server', async () => { + const testDocs = { + 'Łukasiewicz': { value: true }, + 'Sierpiński': { value: true }, + '岩澤': { value: true }, + '🄟': { value: true }, + 'P': { value: true }, + '︒': { value: true }, + '🐵': { value: true } + }; + + return withTestCollection(persistence, testDocs, async collectionRef => { + const orderedQuery = query(collectionRef, orderBy(documentId())); + + const getSnapshot = await getDocsFromServer(orderedQuery); + expect(toIds(getSnapshot)).to.deep.equal([ + 'Sierpiński', + 'Łukasiewicz', + '岩澤', + '︒', + 'P', + '🄟', + '🐵' + ]); + + const storeEvent = new EventsAccumulator(); + const unsubscribe = onSnapshot(orderedQuery, storeEvent.storeEvent); + const watchSnapshot = await storeEvent.awaitEvent(); + expect(toIds(watchSnapshot)).to.deep.equal(toIds(getSnapshot)); + + unsubscribe(); + }); + }); }); }); From 16948bf3d04a78b8de1f9b9ec1e4b4149b181353 Mon Sep 17 00:00:00 2001 From: milaGGL <107142260+milaGGL@users.noreply.github.com> Date: Fri, 10 Jan 2025 11:08:01 -0500 Subject: [PATCH 05/13] format --- .../{comparator.ts => byteComparator.ts} | 0 packages/firestore/src/model/path.ts | 5 ++- packages/firestore/src/model/values.ts | 3 +- .../test/integration/api/database.test.ts | 41 +++---------------- 4 files changed, 9 insertions(+), 40 deletions(-) rename packages/firestore/src/model/{comparator.ts => byteComparator.ts} (100%) diff --git a/packages/firestore/src/model/comparator.ts b/packages/firestore/src/model/byteComparator.ts similarity index 100% rename from packages/firestore/src/model/comparator.ts rename to packages/firestore/src/model/byteComparator.ts diff --git a/packages/firestore/src/model/path.ts b/packages/firestore/src/model/path.ts index 2225b966c0f..6782e2e0846 100644 --- a/packages/firestore/src/model/path.ts +++ b/packages/firestore/src/model/path.ts @@ -19,8 +19,9 @@ import { Integer } from '@firebase/webchannel-wrapper/bloom-blob'; import { debugAssert, fail } from '../util/assert'; import { Code, FirestoreError } from '../util/error'; +import { primitiveComparator } from '../util/misc'; -import { compareUtf8Strings } from './comparator'; +import { compareUtf8Strings } from './byteComparator'; export const DOCUMENT_KEY_NAME = '__name__'; @@ -183,7 +184,7 @@ abstract class BasePath> { return comparison; } } - return Math.sign(p1.length - p2.length); + return primitiveComparator(p1.length, p2.length); } private static compareSegments(lhs: string, rhs: string): number { diff --git a/packages/firestore/src/model/values.ts b/packages/firestore/src/model/values.ts index 778e9ca582b..5297bf22673 100644 --- a/packages/firestore/src/model/values.ts +++ b/packages/firestore/src/model/values.ts @@ -29,7 +29,7 @@ import { arrayEquals, primitiveComparator } from '../util/misc'; import { forEach, objectSize } from '../util/obj'; import { isNegativeZero } from '../util/types'; -import { compareBlobs, compareUtf8Strings } from './comparator'; +import { compareBlobs, compareUtf8Strings } from './byteComparator'; import { DocumentKey } from './document_key'; import { normalizeByteString, @@ -253,7 +253,6 @@ export function valueCompare(left: Value, right: Value): number { ); case TypeOrder.StringValue: return compareUtf8Strings(left.stringValue!, right.stringValue!); - // return primitiveComparator(left.stringValue!, right.stringValue!); case TypeOrder.BlobValue: return compareBlobs(left.bytesValue!, right.bytesValue!); case TypeOrder.RefValue: diff --git a/packages/firestore/test/integration/api/database.test.ts b/packages/firestore/test/integration/api/database.test.ts index 1464a5c46ef..b0344b7e9fd 100644 --- a/packages/firestore/test/integration/api/database.test.ts +++ b/packages/firestore/test/integration/api/database.test.ts @@ -2426,6 +2426,7 @@ apiDescribe('Database', persistence => { }); describe('Unicode strings', () => { + const expectedResult = ['b', 'a', 'c', 'f', 'e', 'd', 'g']; it('snapshot listener sorts unicode strings the same as server', async () => { const testDocs = { 'a': { value: 'Łukasiewicz' }, @@ -2441,15 +2442,7 @@ apiDescribe('Database', persistence => { const orderedQuery = query(collectionRef, orderBy('value')); const getSnapshot = await getDocsFromServer(orderedQuery); - expect(toIds(getSnapshot)).to.deep.equal([ - 'b', - 'a', - 'c', - 'f', - 'e', - 'd', - 'g' - ]); + expect(toIds(getSnapshot)).to.deep.equal(expectedResult); const storeEvent = new EventsAccumulator(); const unsubscribe = onSnapshot(orderedQuery, storeEvent.storeEvent); @@ -2475,15 +2468,7 @@ apiDescribe('Database', persistence => { const orderedQuery = query(collectionRef, orderBy('value')); const getSnapshot = await getDocsFromServer(orderedQuery); - expect(toIds(getSnapshot)).to.deep.equal([ - 'b', - 'a', - 'c', - 'f', - 'e', - 'd', - 'g' - ]); + expect(toIds(getSnapshot)).to.deep.equal(expectedResult); const storeEvent = new EventsAccumulator(); const unsubscribe = onSnapshot(orderedQuery, storeEvent.storeEvent); @@ -2509,15 +2494,7 @@ apiDescribe('Database', persistence => { const orderedQuery = query(collectionRef, orderBy('value')); const getSnapshot = await getDocsFromServer(orderedQuery); - expect(toIds(getSnapshot)).to.deep.equal([ - 'b', - 'a', - 'c', - 'f', - 'e', - 'd', - 'g' - ]); + expect(toIds(getSnapshot)).to.deep.equal(expectedResult); const storeEvent = new EventsAccumulator(); const unsubscribe = onSnapshot(orderedQuery, storeEvent.storeEvent); @@ -2543,15 +2520,7 @@ apiDescribe('Database', persistence => { const orderedQuery = query(collectionRef, orderBy('value')); const getSnapshot = await getDocsFromServer(orderedQuery); - expect(toIds(getSnapshot)).to.deep.equal([ - 'b', - 'a', - 'c', - 'f', - 'e', - 'd', - 'g' - ]); + expect(toIds(getSnapshot)).to.deep.equal(expectedResult); const storeEvent = new EventsAccumulator(); const unsubscribe = onSnapshot(orderedQuery, storeEvent.storeEvent); From 68badf4212e837d8de566b9cd866403b91c87a1f Mon Sep 17 00:00:00 2001 From: milaGGL <107142260+milaGGL@users.noreply.github.com> Date: Fri, 10 Jan 2025 13:01:13 -0500 Subject: [PATCH 06/13] remove docs-devsite change --- docs-devsite/_toc.yaml | 128 +++++++++------- docs-devsite/index.md | 3 +- docs-devsite/vertexai-preview.baseparams.md | 42 ------ docs-devsite/vertexai-preview.chatsession.md | 138 ------------------ docs-devsite/vertexai-preview.citation.md | 78 ---------- .../vertexai-preview.citationmetadata.md | 33 ----- docs-devsite/vertexai-preview.content.md | 42 ------ .../vertexai-preview.counttokensrequest.md | 33 ----- .../vertexai-preview.counttokensresponse.md | 46 ------ docs-devsite/vertexai-preview.date_2.md | 51 ------- ...preview.enhancedgeneratecontentresponse.md | 45 ------ 11 files changed, 79 insertions(+), 560 deletions(-) delete mode 100644 docs-devsite/vertexai-preview.baseparams.md delete mode 100644 docs-devsite/vertexai-preview.chatsession.md delete mode 100644 docs-devsite/vertexai-preview.citation.md delete mode 100644 docs-devsite/vertexai-preview.citationmetadata.md delete mode 100644 docs-devsite/vertexai-preview.content.md delete mode 100644 docs-devsite/vertexai-preview.counttokensrequest.md delete mode 100644 docs-devsite/vertexai-preview.counttokensresponse.md delete mode 100644 docs-devsite/vertexai-preview.date_2.md delete mode 100644 docs-devsite/vertexai-preview.enhancedgeneratecontentresponse.md diff --git a/docs-devsite/_toc.yaml b/docs-devsite/_toc.yaml index a8217a15f6b..46a9053e153 100644 --- a/docs-devsite/_toc.yaml +++ b/docs-devsite/_toc.yaml @@ -428,6 +428,8 @@ toc: - title: remote-config path: /docs/reference/js/remote-config.md section: + - title: CustomSignals + path: /docs/reference/js/remote-config.customsignals.md - title: RemoteConfig path: /docs/reference/js/remote-config.remoteconfig.md - title: RemoteConfigSettings @@ -461,98 +463,124 @@ toc: path: /docs/reference/js/storage.uploadtask.md - title: UploadTaskSnapshot path: /docs/reference/js/storage.uploadtasksnapshot.md -- title: vertexai-preview - path: /docs/reference/js/vertexai-preview.md +- title: vertexai + path: /docs/reference/js/vertexai.md section: + - title: ArraySchema + path: /docs/reference/js/vertexai.arrayschema.md - title: BaseParams - path: /docs/reference/js/vertexai-preview.baseparams.md + path: /docs/reference/js/vertexai.baseparams.md + - title: BooleanSchema + path: /docs/reference/js/vertexai.booleanschema.md - title: ChatSession - path: /docs/reference/js/vertexai-preview.chatsession.md + path: /docs/reference/js/vertexai.chatsession.md - title: Citation - path: /docs/reference/js/vertexai-preview.citation.md + path: /docs/reference/js/vertexai.citation.md - title: CitationMetadata - path: /docs/reference/js/vertexai-preview.citationmetadata.md + path: /docs/reference/js/vertexai.citationmetadata.md - title: Content - path: /docs/reference/js/vertexai-preview.content.md + path: /docs/reference/js/vertexai.content.md - title: CountTokensRequest - path: /docs/reference/js/vertexai-preview.counttokensrequest.md + path: /docs/reference/js/vertexai.counttokensrequest.md - title: CountTokensResponse - path: /docs/reference/js/vertexai-preview.counttokensresponse.md + path: /docs/reference/js/vertexai.counttokensresponse.md + - title: CustomErrorData + path: /docs/reference/js/vertexai.customerrordata.md - title: Date_2 - path: /docs/reference/js/vertexai-preview.date_2.md + path: /docs/reference/js/vertexai.date_2.md - title: EnhancedGenerateContentResponse - path: /docs/reference/js/vertexai-preview.enhancedgeneratecontentresponse.md + path: /docs/reference/js/vertexai.enhancedgeneratecontentresponse.md + - title: ErrorDetails + path: /docs/reference/js/vertexai.errordetails.md - title: FileData - path: /docs/reference/js/vertexai-preview.filedata.md + path: /docs/reference/js/vertexai.filedata.md - title: FileDataPart - path: /docs/reference/js/vertexai-preview.filedatapart.md + path: /docs/reference/js/vertexai.filedatapart.md - title: FunctionCall - path: /docs/reference/js/vertexai-preview.functioncall.md + path: /docs/reference/js/vertexai.functioncall.md - title: FunctionCallingConfig - path: /docs/reference/js/vertexai-preview.functioncallingconfig.md + path: /docs/reference/js/vertexai.functioncallingconfig.md - title: FunctionCallPart - path: /docs/reference/js/vertexai-preview.functioncallpart.md + path: /docs/reference/js/vertexai.functioncallpart.md - title: FunctionDeclaration - path: /docs/reference/js/vertexai-preview.functiondeclaration.md - - title: FunctionDeclarationSchema - path: /docs/reference/js/vertexai-preview.functiondeclarationschema.md - - title: FunctionDeclarationSchemaProperty - path: /docs/reference/js/vertexai-preview.functiondeclarationschemaproperty.md + path: /docs/reference/js/vertexai.functiondeclaration.md - title: FunctionDeclarationsTool - path: /docs/reference/js/vertexai-preview.functiondeclarationstool.md + path: /docs/reference/js/vertexai.functiondeclarationstool.md - title: FunctionResponse - path: /docs/reference/js/vertexai-preview.functionresponse.md + path: /docs/reference/js/vertexai.functionresponse.md - title: FunctionResponsePart - path: /docs/reference/js/vertexai-preview.functionresponsepart.md + path: /docs/reference/js/vertexai.functionresponsepart.md - title: GenerateContentCandidate - path: /docs/reference/js/vertexai-preview.generatecontentcandidate.md + path: /docs/reference/js/vertexai.generatecontentcandidate.md - title: GenerateContentRequest - path: /docs/reference/js/vertexai-preview.generatecontentrequest.md + path: /docs/reference/js/vertexai.generatecontentrequest.md - title: GenerateContentResponse - path: /docs/reference/js/vertexai-preview.generatecontentresponse.md + path: /docs/reference/js/vertexai.generatecontentresponse.md - title: GenerateContentResult - path: /docs/reference/js/vertexai-preview.generatecontentresult.md + path: /docs/reference/js/vertexai.generatecontentresult.md - title: GenerateContentStreamResult - path: /docs/reference/js/vertexai-preview.generatecontentstreamresult.md + path: /docs/reference/js/vertexai.generatecontentstreamresult.md - title: GenerationConfig - path: /docs/reference/js/vertexai-preview.generationconfig.md + path: /docs/reference/js/vertexai.generationconfig.md - title: GenerativeContentBlob - path: /docs/reference/js/vertexai-preview.generativecontentblob.md + path: /docs/reference/js/vertexai.generativecontentblob.md - title: GenerativeModel - path: /docs/reference/js/vertexai-preview.generativemodel.md + path: /docs/reference/js/vertexai.generativemodel.md - title: GroundingAttribution - path: /docs/reference/js/vertexai-preview.groundingattribution.md + path: /docs/reference/js/vertexai.groundingattribution.md - title: GroundingMetadata - path: /docs/reference/js/vertexai-preview.groundingmetadata.md + path: /docs/reference/js/vertexai.groundingmetadata.md - title: InlineDataPart - path: /docs/reference/js/vertexai-preview.inlinedatapart.md + path: /docs/reference/js/vertexai.inlinedatapart.md + - title: IntegerSchema + path: /docs/reference/js/vertexai.integerschema.md - title: ModelParams - path: /docs/reference/js/vertexai-preview.modelparams.md + path: /docs/reference/js/vertexai.modelparams.md + - title: NumberSchema + path: /docs/reference/js/vertexai.numberschema.md + - title: ObjectSchema + path: /docs/reference/js/vertexai.objectschema.md + - title: ObjectSchemaInterface + path: /docs/reference/js/vertexai.objectschemainterface.md - title: PromptFeedback - path: /docs/reference/js/vertexai-preview.promptfeedback.md + path: /docs/reference/js/vertexai.promptfeedback.md - title: RequestOptions - path: /docs/reference/js/vertexai-preview.requestoptions.md + path: /docs/reference/js/vertexai.requestoptions.md - title: RetrievedContextAttribution - path: /docs/reference/js/vertexai-preview.retrievedcontextattribution.md + path: /docs/reference/js/vertexai.retrievedcontextattribution.md - title: SafetyRating - path: /docs/reference/js/vertexai-preview.safetyrating.md + path: /docs/reference/js/vertexai.safetyrating.md - title: SafetySetting - path: /docs/reference/js/vertexai-preview.safetysetting.md + path: /docs/reference/js/vertexai.safetysetting.md + - title: Schema + path: /docs/reference/js/vertexai.schema.md + - title: SchemaInterface + path: /docs/reference/js/vertexai.schemainterface.md + - title: SchemaParams + path: /docs/reference/js/vertexai.schemaparams.md + - title: SchemaRequest + path: /docs/reference/js/vertexai.schemarequest.md + - title: SchemaShared + path: /docs/reference/js/vertexai.schemashared.md - title: Segment - path: /docs/reference/js/vertexai-preview.segment.md + path: /docs/reference/js/vertexai.segment.md - title: StartChatParams - path: /docs/reference/js/vertexai-preview.startchatparams.md + path: /docs/reference/js/vertexai.startchatparams.md + - title: StringSchema + path: /docs/reference/js/vertexai.stringschema.md - title: TextPart - path: /docs/reference/js/vertexai-preview.textpart.md + path: /docs/reference/js/vertexai.textpart.md - title: ToolConfig - path: /docs/reference/js/vertexai-preview.toolconfig.md + path: /docs/reference/js/vertexai.toolconfig.md - title: UsageMetadata - path: /docs/reference/js/vertexai-preview.usagemetadata.md + path: /docs/reference/js/vertexai.usagemetadata.md - title: VertexAI - path: /docs/reference/js/vertexai-preview.vertexai.md + path: /docs/reference/js/vertexai.vertexai.md + - title: VertexAIError + path: /docs/reference/js/vertexai.vertexaierror.md - title: VertexAIOptions - path: /docs/reference/js/vertexai-preview.vertexaioptions.md + path: /docs/reference/js/vertexai.vertexaioptions.md - title: VideoMetadata - path: /docs/reference/js/vertexai-preview.videometadata.md + path: /docs/reference/js/vertexai.videometadata.md - title: WebAttribution - path: /docs/reference/js/vertexai-preview.webattribution.md + path: /docs/reference/js/vertexai.webattribution.md \ No newline at end of file diff --git a/docs-devsite/index.md b/docs-devsite/index.md index 2c22b58d80c..36e55d452a6 100644 --- a/docs-devsite/index.md +++ b/docs-devsite/index.md @@ -27,5 +27,4 @@ https://github.com/firebase/firebase-js-sdk | [@firebase/performance](./performance.md#performance_package) | The Firebase Performance Monitoring Web SDK. This SDK does not work in a Node.js environment. | | [@firebase/remote-config](./remote-config.md#remote-config_package) | The Firebase Remote Config Web SDK. This SDK does not work in a Node.js environment. | | [@firebase/storage](./storage.md#storage_package) | Cloud Storage for Firebase | -| [@firebase/vertexai-preview](./vertexai-preview.md#vertexai-preview_package) | The Vertex AI For Firebase Web SDK. | - +| [@firebase/vertexai](./vertexai.md#vertexai_package) | The Vertex AI in Firebase Web SDK. | diff --git a/docs-devsite/vertexai-preview.baseparams.md b/docs-devsite/vertexai-preview.baseparams.md deleted file mode 100644 index 6756c919ccc..00000000000 --- a/docs-devsite/vertexai-preview.baseparams.md +++ /dev/null @@ -1,42 +0,0 @@ -Project: /docs/reference/js/_project.yaml -Book: /docs/reference/_book.yaml -page_type: reference - -{% comment %} -DO NOT EDIT THIS FILE! -This is generated by the JS SDK team, and any local changes will be -overwritten. Changes should be made in the source code at -https://github.com/firebase/firebase-js-sdk -{% endcomment %} - -# BaseParams interface -Base parameters for a number of methods. - -Signature: - -```typescript -export interface BaseParams -``` - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [generationConfig](./vertexai-preview.baseparams.md#baseparamsgenerationconfig) | [GenerationConfig](./vertexai-preview.generationconfig.md#generationconfig_interface) | | -| [safetySettings](./vertexai-preview.baseparams.md#baseparamssafetysettings) | [SafetySetting](./vertexai-preview.safetysetting.md#safetysetting_interface)\[\] | | - -## BaseParams.generationConfig - -Signature: - -```typescript -generationConfig?: GenerationConfig; -``` - -## BaseParams.safetySettings - -Signature: - -```typescript -safetySettings?: SafetySetting[]; -``` diff --git a/docs-devsite/vertexai-preview.chatsession.md b/docs-devsite/vertexai-preview.chatsession.md deleted file mode 100644 index 3d78bab3745..00000000000 --- a/docs-devsite/vertexai-preview.chatsession.md +++ /dev/null @@ -1,138 +0,0 @@ -Project: /docs/reference/js/_project.yaml -Book: /docs/reference/_book.yaml -page_type: reference - -{% comment %} -DO NOT EDIT THIS FILE! -This is generated by the JS SDK team, and any local changes will be -overwritten. Changes should be made in the source code at -https://github.com/firebase/firebase-js-sdk -{% endcomment %} - -# ChatSession class -ChatSession class that enables sending chat messages and stores history of sent and received messages so far. - -Signature: - -```typescript -export declare class ChatSession -``` - -## Constructors - -| Constructor | Modifiers | Description | -| --- | --- | --- | -| [(constructor)(apiSettings, model, params, requestOptions)](./vertexai-preview.chatsession.md#chatsessionconstructor) | | Constructs a new instance of the ChatSession class | - -## Properties - -| Property | Modifiers | Type | Description | -| --- | --- | --- | --- | -| [model](./vertexai-preview.chatsession.md#chatsessionmodel) | | string | | -| [params](./vertexai-preview.chatsession.md#chatsessionparams) | | [StartChatParams](./vertexai-preview.startchatparams.md#startchatparams_interface) \| undefined | | -| [requestOptions](./vertexai-preview.chatsession.md#chatsessionrequestoptions) | | [RequestOptions](./vertexai-preview.requestoptions.md#requestoptions_interface) \| undefined | | - -## Methods - -| Method | Modifiers | Description | -| --- | --- | --- | -| [getHistory()](./vertexai-preview.chatsession.md#chatsessiongethistory) | | Gets the chat history so far. Blocked prompts are not added to history. Blocked candidates are not added to history, nor are the prompts that generated them. | -| [sendMessage(request)](./vertexai-preview.chatsession.md#chatsessionsendmessage) | | Sends a chat message and receives a non-streaming [GenerateContentResult](./vertexai-preview.generatecontentresult.md#generatecontentresult_interface) | -| [sendMessageStream(request)](./vertexai-preview.chatsession.md#chatsessionsendmessagestream) | | Sends a chat message and receives the response as a [GenerateContentStreamResult](./vertexai-preview.generatecontentstreamresult.md#generatecontentstreamresult_interface) containing an iterable stream and a response promise. | - -## ChatSession.(constructor) - -Constructs a new instance of the `ChatSession` class - -Signature: - -```typescript -constructor(apiSettings: ApiSettings, model: string, params?: StartChatParams | undefined, requestOptions?: RequestOptions | undefined); -``` - -#### Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| apiSettings | ApiSettings | | -| model | string | | -| params | [StartChatParams](./vertexai-preview.startchatparams.md#startchatparams_interface) \| undefined | | -| requestOptions | [RequestOptions](./vertexai-preview.requestoptions.md#requestoptions_interface) \| undefined | | - -## ChatSession.model - -Signature: - -```typescript -model: string; -``` - -## ChatSession.params - -Signature: - -```typescript -params?: StartChatParams | undefined; -``` - -## ChatSession.requestOptions - -Signature: - -```typescript -requestOptions?: RequestOptions | undefined; -``` - -## ChatSession.getHistory() - -Gets the chat history so far. Blocked prompts are not added to history. Blocked candidates are not added to history, nor are the prompts that generated them. - -Signature: - -```typescript -getHistory(): Promise; -``` -Returns: - -Promise<[Content](./vertexai-preview.content.md#content_interface)\[\]> - -## ChatSession.sendMessage() - -Sends a chat message and receives a non-streaming [GenerateContentResult](./vertexai-preview.generatecontentresult.md#generatecontentresult_interface) - -Signature: - -```typescript -sendMessage(request: string | Array): Promise; -``` - -#### Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| request | string \| Array<string \| [Part](./vertexai-preview.md#part)> | | - -Returns: - -Promise<[GenerateContentResult](./vertexai-preview.generatecontentresult.md#generatecontentresult_interface)> - -## ChatSession.sendMessageStream() - -Sends a chat message and receives the response as a [GenerateContentStreamResult](./vertexai-preview.generatecontentstreamresult.md#generatecontentstreamresult_interface) containing an iterable stream and a response promise. - -Signature: - -```typescript -sendMessageStream(request: string | Array): Promise; -``` - -#### Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| request | string \| Array<string \| [Part](./vertexai-preview.md#part)> | | - -Returns: - -Promise<[GenerateContentStreamResult](./vertexai-preview.generatecontentstreamresult.md#generatecontentstreamresult_interface)> - diff --git a/docs-devsite/vertexai-preview.citation.md b/docs-devsite/vertexai-preview.citation.md deleted file mode 100644 index 10a615ee247..00000000000 --- a/docs-devsite/vertexai-preview.citation.md +++ /dev/null @@ -1,78 +0,0 @@ -Project: /docs/reference/js/_project.yaml -Book: /docs/reference/_book.yaml -page_type: reference - -{% comment %} -DO NOT EDIT THIS FILE! -This is generated by the JS SDK team, and any local changes will be -overwritten. Changes should be made in the source code at -https://github.com/firebase/firebase-js-sdk -{% endcomment %} - -# Citation interface -A single citation. - -Signature: - -```typescript -export interface Citation -``` - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [endIndex](./vertexai-preview.citation.md#citationendindex) | number | | -| [license](./vertexai-preview.citation.md#citationlicense) | string | | -| [publicationDate](./vertexai-preview.citation.md#citationpublicationdate) | Date | | -| [startIndex](./vertexai-preview.citation.md#citationstartindex) | number | | -| [title](./vertexai-preview.citation.md#citationtitle) | string | | -| [uri](./vertexai-preview.citation.md#citationuri) | string | | - -## Citation.endIndex - -Signature: - -```typescript -endIndex?: number; -``` - -## Citation.license - -Signature: - -```typescript -license?: string; -``` - -## Citation.publicationDate - -Signature: - -```typescript -publicationDate?: Date; -``` - -## Citation.startIndex - -Signature: - -```typescript -startIndex?: number; -``` - -## Citation.title - -Signature: - -```typescript -title?: string; -``` - -## Citation.uri - -Signature: - -```typescript -uri?: string; -``` diff --git a/docs-devsite/vertexai-preview.citationmetadata.md b/docs-devsite/vertexai-preview.citationmetadata.md deleted file mode 100644 index fa740ca1af7..00000000000 --- a/docs-devsite/vertexai-preview.citationmetadata.md +++ /dev/null @@ -1,33 +0,0 @@ -Project: /docs/reference/js/_project.yaml -Book: /docs/reference/_book.yaml -page_type: reference - -{% comment %} -DO NOT EDIT THIS FILE! -This is generated by the JS SDK team, and any local changes will be -overwritten. Changes should be made in the source code at -https://github.com/firebase/firebase-js-sdk -{% endcomment %} - -# CitationMetadata interface -Citation metadata that may be found on a [GenerateContentCandidate](./vertexai-preview.generatecontentcandidate.md#generatecontentcandidate_interface). - -Signature: - -```typescript -export interface CitationMetadata -``` - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [citations](./vertexai-preview.citationmetadata.md#citationmetadatacitations) | [Citation](./vertexai-preview.citation.md#citation_interface)\[\] | | - -## CitationMetadata.citations - -Signature: - -```typescript -citations: Citation[]; -``` diff --git a/docs-devsite/vertexai-preview.content.md b/docs-devsite/vertexai-preview.content.md deleted file mode 100644 index 26198a3951f..00000000000 --- a/docs-devsite/vertexai-preview.content.md +++ /dev/null @@ -1,42 +0,0 @@ -Project: /docs/reference/js/_project.yaml -Book: /docs/reference/_book.yaml -page_type: reference - -{% comment %} -DO NOT EDIT THIS FILE! -This is generated by the JS SDK team, and any local changes will be -overwritten. Changes should be made in the source code at -https://github.com/firebase/firebase-js-sdk -{% endcomment %} - -# Content interface -Content type for both prompts and response candidates. - -Signature: - -```typescript -export interface Content -``` - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [parts](./vertexai-preview.content.md#contentparts) | [Part](./vertexai-preview.md#part)\[\] | | -| [role](./vertexai-preview.content.md#contentrole) | [Role](./vertexai-preview.md#role) | | - -## Content.parts - -Signature: - -```typescript -parts: Part[]; -``` - -## Content.role - -Signature: - -```typescript -role: Role; -``` diff --git a/docs-devsite/vertexai-preview.counttokensrequest.md b/docs-devsite/vertexai-preview.counttokensrequest.md deleted file mode 100644 index 07e5f0d85f3..00000000000 --- a/docs-devsite/vertexai-preview.counttokensrequest.md +++ /dev/null @@ -1,33 +0,0 @@ -Project: /docs/reference/js/_project.yaml -Book: /docs/reference/_book.yaml -page_type: reference - -{% comment %} -DO NOT EDIT THIS FILE! -This is generated by the JS SDK team, and any local changes will be -overwritten. Changes should be made in the source code at -https://github.com/firebase/firebase-js-sdk -{% endcomment %} - -# CountTokensRequest interface -Params for calling [GenerativeModel.countTokens()](./vertexai-preview.generativemodel.md#generativemodelcounttokens) - -Signature: - -```typescript -export interface CountTokensRequest -``` - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [contents](./vertexai-preview.counttokensrequest.md#counttokensrequestcontents) | [Content](./vertexai-preview.content.md#content_interface)\[\] | | - -## CountTokensRequest.contents - -Signature: - -```typescript -contents: Content[]; -``` diff --git a/docs-devsite/vertexai-preview.counttokensresponse.md b/docs-devsite/vertexai-preview.counttokensresponse.md deleted file mode 100644 index d097d5aacff..00000000000 --- a/docs-devsite/vertexai-preview.counttokensresponse.md +++ /dev/null @@ -1,46 +0,0 @@ -Project: /docs/reference/js/_project.yaml -Book: /docs/reference/_book.yaml -page_type: reference - -{% comment %} -DO NOT EDIT THIS FILE! -This is generated by the JS SDK team, and any local changes will be -overwritten. Changes should be made in the source code at -https://github.com/firebase/firebase-js-sdk -{% endcomment %} - -# CountTokensResponse interface -Response from calling [GenerativeModel.countTokens()](./vertexai-preview.generativemodel.md#generativemodelcounttokens). - -Signature: - -```typescript -export interface CountTokensResponse -``` - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [totalBillableCharacters](./vertexai-preview.counttokensresponse.md#counttokensresponsetotalbillablecharacters) | number | The total number of billable characters counted across all instances from the request. | -| [totalTokens](./vertexai-preview.counttokensresponse.md#counttokensresponsetotaltokens) | number | The total number of tokens counted across all instances from the request. | - -## CountTokensResponse.totalBillableCharacters - -The total number of billable characters counted across all instances from the request. - -Signature: - -```typescript -totalBillableCharacters?: number; -``` - -## CountTokensResponse.totalTokens - -The total number of tokens counted across all instances from the request. - -Signature: - -```typescript -totalTokens: number; -``` diff --git a/docs-devsite/vertexai-preview.date_2.md b/docs-devsite/vertexai-preview.date_2.md deleted file mode 100644 index 5af031447c4..00000000000 --- a/docs-devsite/vertexai-preview.date_2.md +++ /dev/null @@ -1,51 +0,0 @@ -Project: /docs/reference/js/_project.yaml -Book: /docs/reference/_book.yaml -page_type: reference - -{% comment %} -DO NOT EDIT THIS FILE! -This is generated by the JS SDK team, and any local changes will be -overwritten. Changes should be made in the source code at -https://github.com/firebase/firebase-js-sdk -{% endcomment %} - -# Date_2 interface -Protobuf google.type.Date - -Signature: - -```typescript -export interface Date -``` - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [day](./vertexai-preview.date_2.md#date_2day) | number | | -| [month](./vertexai-preview.date_2.md#date_2month) | number | | -| [year](./vertexai-preview.date_2.md#date_2year) | number | | - -## Date\_2.day - -Signature: - -```typescript -day: number; -``` - -## Date\_2.month - -Signature: - -```typescript -month: number; -``` - -## Date\_2.year - -Signature: - -```typescript -year: number; -``` diff --git a/docs-devsite/vertexai-preview.enhancedgeneratecontentresponse.md b/docs-devsite/vertexai-preview.enhancedgeneratecontentresponse.md deleted file mode 100644 index 132c5ed0be2..00000000000 --- a/docs-devsite/vertexai-preview.enhancedgeneratecontentresponse.md +++ /dev/null @@ -1,45 +0,0 @@ -Project: /docs/reference/js/_project.yaml -Book: /docs/reference/_book.yaml -page_type: reference - -{% comment %} -DO NOT EDIT THIS FILE! -This is generated by the JS SDK team, and any local changes will be -overwritten. Changes should be made in the source code at -https://github.com/firebase/firebase-js-sdk -{% endcomment %} - -# EnhancedGenerateContentResponse interface -Response object wrapped with helper methods. - -Signature: - -```typescript -export interface EnhancedGenerateContentResponse extends GenerateContentResponse -``` -Extends: [GenerateContentResponse](./vertexai-preview.generatecontentresponse.md#generatecontentresponse_interface) - -## Properties - -| Property | Type | Description | -| --- | --- | --- | -| [functionCalls](./vertexai-preview.enhancedgeneratecontentresponse.md#enhancedgeneratecontentresponsefunctioncalls) | () => [FunctionCall](./vertexai-preview.functioncall.md#functioncall_interface)\[\] \| undefined | | -| [text](./vertexai-preview.enhancedgeneratecontentresponse.md#enhancedgeneratecontentresponsetext) | () => string | Returns the text string from the response, if available. Throws if the prompt or candidate was blocked. | - -## EnhancedGenerateContentResponse.functionCalls - -Signature: - -```typescript -functionCalls: () => FunctionCall[] | undefined; -``` - -## EnhancedGenerateContentResponse.text - -Returns the text string from the response, if available. Throws if the prompt or candidate was blocked. - -Signature: - -```typescript -text: () => string; -``` From 26d8839dffc2249bcad9b0099d8999ab3f0b3407 Mon Sep 17 00:00:00 2001 From: milaGGL <107142260+milaGGL@users.noreply.github.com> Date: Fri, 10 Jan 2025 13:04:35 -0500 Subject: [PATCH 07/13] remove docs-devsite change --- docs-devsite/_toc.yaml | 2 -- docs-devsite/index.md | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/docs-devsite/_toc.yaml b/docs-devsite/_toc.yaml index 46a9053e153..354ccc9c628 100644 --- a/docs-devsite/_toc.yaml +++ b/docs-devsite/_toc.yaml @@ -428,8 +428,6 @@ toc: - title: remote-config path: /docs/reference/js/remote-config.md section: - - title: CustomSignals - path: /docs/reference/js/remote-config.customsignals.md - title: RemoteConfig path: /docs/reference/js/remote-config.remoteconfig.md - title: RemoteConfigSettings diff --git a/docs-devsite/index.md b/docs-devsite/index.md index 36e55d452a6..4e41b6d2aef 100644 --- a/docs-devsite/index.md +++ b/docs-devsite/index.md @@ -27,4 +27,4 @@ https://github.com/firebase/firebase-js-sdk | [@firebase/performance](./performance.md#performance_package) | The Firebase Performance Monitoring Web SDK. This SDK does not work in a Node.js environment. | | [@firebase/remote-config](./remote-config.md#remote-config_package) | The Firebase Remote Config Web SDK. This SDK does not work in a Node.js environment. | | [@firebase/storage](./storage.md#storage_package) | Cloud Storage for Firebase | -| [@firebase/vertexai](./vertexai.md#vertexai_package) | The Vertex AI in Firebase Web SDK. | +| [@firebase/vertexai](./vertexai.md#vertexai_package) | The Vertex AI in Firebase Web SDK. | \ No newline at end of file From 65981c39b6d527d903ef1de80fcdb5459a50fd12 Mon Sep 17 00:00:00 2001 From: milaGGL <107142260+milaGGL@users.noreply.github.com> Date: Fri, 10 Jan 2025 15:57:03 -0500 Subject: [PATCH 08/13] format --- docs-devsite/_toc.yaml | 2 +- docs-devsite/index.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs-devsite/_toc.yaml b/docs-devsite/_toc.yaml index 354ccc9c628..ca06d4f9398 100644 --- a/docs-devsite/_toc.yaml +++ b/docs-devsite/_toc.yaml @@ -581,4 +581,4 @@ toc: - title: VideoMetadata path: /docs/reference/js/vertexai.videometadata.md - title: WebAttribution - path: /docs/reference/js/vertexai.webattribution.md \ No newline at end of file + path: /docs/reference/js/vertexai.webattribution.md diff --git a/docs-devsite/index.md b/docs-devsite/index.md index 4e41b6d2aef..36e55d452a6 100644 --- a/docs-devsite/index.md +++ b/docs-devsite/index.md @@ -27,4 +27,4 @@ https://github.com/firebase/firebase-js-sdk | [@firebase/performance](./performance.md#performance_package) | The Firebase Performance Monitoring Web SDK. This SDK does not work in a Node.js environment. | | [@firebase/remote-config](./remote-config.md#remote-config_package) | The Firebase Remote Config Web SDK. This SDK does not work in a Node.js environment. | | [@firebase/storage](./storage.md#storage_package) | Cloud Storage for Firebase | -| [@firebase/vertexai](./vertexai.md#vertexai_package) | The Vertex AI in Firebase Web SDK. | \ No newline at end of file +| [@firebase/vertexai](./vertexai.md#vertexai_package) | The Vertex AI in Firebase Web SDK. | From 7de7220f8b5dc5cb590b7ccf10b01e5ddfc18a24 Mon Sep 17 00:00:00 2001 From: milaGGL <107142260+milaGGL@users.noreply.github.com> Date: Fri, 10 Jan 2025 16:49:49 -0500 Subject: [PATCH 09/13] add comments --- .../local/indexeddb_remote_document_cache.ts | 4 ++ .../firestore/src/model/byteComparator.ts | 39 ----------- packages/firestore/src/model/path.ts | 4 +- packages/firestore/src/model/values.ts | 16 ++++- packages/firestore/src/util/misc.ts | 16 +++++ .../test/integration/api/database.test.ts | 70 ++++++++++++++++--- 6 files changed, 97 insertions(+), 52 deletions(-) delete mode 100644 packages/firestore/src/model/byteComparator.ts diff --git a/packages/firestore/src/local/indexeddb_remote_document_cache.ts b/packages/firestore/src/local/indexeddb_remote_document_cache.ts index b3d4658d53d..9b23c64fcf5 100644 --- a/packages/firestore/src/local/indexeddb_remote_document_cache.ts +++ b/packages/firestore/src/local/indexeddb_remote_document_cache.ts @@ -655,5 +655,9 @@ export function dbKeyComparator(l: DocumentKey, r: DocumentKey): number { return cmp; } + // TODO(b/329441702): Document IDs should be sorted by UTF-8 encoded byte + // order, but IndexedDB sorts strings lexicographically. Document ID + // comparison here still relies on primitive comparison to avoid mismatches + // observed in snapshot listeners with Unicode characters in documentIds return primitiveComparator(left[left.length - 1], right[right.length - 1]); } diff --git a/packages/firestore/src/model/byteComparator.ts b/packages/firestore/src/model/byteComparator.ts deleted file mode 100644 index e4a0b01fa5c..00000000000 --- a/packages/firestore/src/model/byteComparator.ts +++ /dev/null @@ -1,39 +0,0 @@ -/** - * @license - * Copyright 2025 Google LLC - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -import { normalizeByteString } from './normalize'; - -function stringValueToUint8Array(stringValue: string): Uint8Array { - // Use TextEncoder to convert the string to UTF-8 encoded bytes - const encoder = new TextEncoder(); - return encoder.encode(stringValue); -} - -export function compareUtf8Strings(left: string, right: string): number { - const leftBytes = stringValueToUint8Array(left); - const rightBytes = stringValueToUint8Array(right); - return compareBlobs(leftBytes, rightBytes); -} - -export function compareBlobs( - left: string | Uint8Array, - right: string | Uint8Array -): number { - const leftBytes = normalizeByteString(left); - const rightBytes = normalizeByteString(right); - return leftBytes.compareTo(rightBytes); -} diff --git a/packages/firestore/src/model/path.ts b/packages/firestore/src/model/path.ts index 6782e2e0846..e7aeb6f61cc 100644 --- a/packages/firestore/src/model/path.ts +++ b/packages/firestore/src/model/path.ts @@ -19,9 +19,7 @@ import { Integer } from '@firebase/webchannel-wrapper/bloom-blob'; import { debugAssert, fail } from '../util/assert'; import { Code, FirestoreError } from '../util/error'; -import { primitiveComparator } from '../util/misc'; - -import { compareUtf8Strings } from './byteComparator'; +import { primitiveComparator, compareUtf8Strings } from '../util/misc'; export const DOCUMENT_KEY_NAME = '__name__'; diff --git a/packages/firestore/src/model/values.ts b/packages/firestore/src/model/values.ts index 5297bf22673..2e3417e674f 100644 --- a/packages/firestore/src/model/values.ts +++ b/packages/firestore/src/model/values.ts @@ -25,11 +25,14 @@ import { Value } from '../protos/firestore_proto_api'; import { fail } from '../util/assert'; -import { arrayEquals, primitiveComparator } from '../util/misc'; +import { + arrayEquals, + primitiveComparator, + compareUtf8Strings +} from '../util/misc'; import { forEach, objectSize } from '../util/obj'; import { isNegativeZero } from '../util/types'; -import { compareBlobs, compareUtf8Strings } from './byteComparator'; import { DocumentKey } from './document_key'; import { normalizeByteString, @@ -338,6 +341,15 @@ function compareGeoPoints(left: LatLng, right: LatLng): number { ); } +function compareBlobs( + left: string | Uint8Array, + right: string | Uint8Array +): number { + const leftBytes = normalizeByteString(left); + const rightBytes = normalizeByteString(right); + return leftBytes.compareTo(rightBytes); +} + function compareArrays(left: ArrayValue, right: ArrayValue): number { const leftArray = left.values || []; const rightArray = right.values || []; diff --git a/packages/firestore/src/util/misc.ts b/packages/firestore/src/util/misc.ts index acaff77abb6..4a508553e75 100644 --- a/packages/firestore/src/util/misc.ts +++ b/packages/firestore/src/util/misc.ts @@ -74,6 +74,22 @@ export interface Equatable { isEqual(other: T): boolean; } +/** Compare strings in UTF-8 encoded byte order */ +export function compareUtf8Strings(left: string, right: string): number { + // Convert the string to UTF-8 encoded bytes + const encodedLeft = new TextEncoder().encode(left); + const encodedRight = new TextEncoder().encode(right); + + for (let i = 0; i < Math.min(encodedLeft.length, encodedRight.length); i++) { + const comparison = primitiveComparator(encodedLeft[i], encodedRight[i]); + if (comparison !== 0) { + return comparison; + } + } + + return primitiveComparator(encodedLeft.length, encodedRight.length); +} + export interface Iterable { forEach: (cb: (v: V) => void) => void; } diff --git a/packages/firestore/test/integration/api/database.test.ts b/packages/firestore/test/integration/api/database.test.ts index b0344b7e9fd..1304b7b4aba 100644 --- a/packages/firestore/test/integration/api/database.test.ts +++ b/packages/firestore/test/integration/api/database.test.ts @@ -2425,8 +2425,8 @@ apiDescribe('Database', persistence => { }); }); - describe('Unicode strings', () => { - const expectedResult = ['b', 'a', 'c', 'f', 'e', 'd', 'g']; + describe('Sort unicode strings', () => { + const expectedDocs = ['b', 'a', 'c', 'f', 'e', 'd', 'g']; it('snapshot listener sorts unicode strings the same as server', async () => { const testDocs = { 'a': { value: 'Łukasiewicz' }, @@ -2442,7 +2442,7 @@ apiDescribe('Database', persistence => { const orderedQuery = query(collectionRef, orderBy('value')); const getSnapshot = await getDocsFromServer(orderedQuery); - expect(toIds(getSnapshot)).to.deep.equal(expectedResult); + expect(toIds(getSnapshot)).to.deep.equal(expectedDocs); const storeEvent = new EventsAccumulator(); const unsubscribe = onSnapshot(orderedQuery, storeEvent.storeEvent); @@ -2450,6 +2450,8 @@ apiDescribe('Database', persistence => { expect(toIds(watchSnapshot)).to.deep.equal(toIds(getSnapshot)); unsubscribe(); + + await checkOnlineAndOfflineResultsMatch(orderedQuery, ...expectedDocs); }); }); @@ -2468,7 +2470,7 @@ apiDescribe('Database', persistence => { const orderedQuery = query(collectionRef, orderBy('value')); const getSnapshot = await getDocsFromServer(orderedQuery); - expect(toIds(getSnapshot)).to.deep.equal(expectedResult); + expect(toIds(getSnapshot)).to.deep.equal(expectedDocs); const storeEvent = new EventsAccumulator(); const unsubscribe = onSnapshot(orderedQuery, storeEvent.storeEvent); @@ -2476,6 +2478,8 @@ apiDescribe('Database', persistence => { expect(toIds(watchSnapshot)).to.deep.equal(toIds(getSnapshot)); unsubscribe(); + + await checkOnlineAndOfflineResultsMatch(orderedQuery, ...expectedDocs); }); }); @@ -2494,7 +2498,7 @@ apiDescribe('Database', persistence => { const orderedQuery = query(collectionRef, orderBy('value')); const getSnapshot = await getDocsFromServer(orderedQuery); - expect(toIds(getSnapshot)).to.deep.equal(expectedResult); + expect(toIds(getSnapshot)).to.deep.equal(expectedDocs); const storeEvent = new EventsAccumulator(); const unsubscribe = onSnapshot(orderedQuery, storeEvent.storeEvent); @@ -2502,6 +2506,8 @@ apiDescribe('Database', persistence => { expect(toIds(watchSnapshot)).to.deep.equal(toIds(getSnapshot)); unsubscribe(); + + await checkOnlineAndOfflineResultsMatch(orderedQuery, ...expectedDocs); }); }); @@ -2520,7 +2526,7 @@ apiDescribe('Database', persistence => { const orderedQuery = query(collectionRef, orderBy('value')); const getSnapshot = await getDocsFromServer(orderedQuery); - expect(toIds(getSnapshot)).to.deep.equal(expectedResult); + expect(toIds(getSnapshot)).to.deep.equal(expectedDocs); const storeEvent = new EventsAccumulator(); const unsubscribe = onSnapshot(orderedQuery, storeEvent.storeEvent); @@ -2528,6 +2534,8 @@ apiDescribe('Database', persistence => { expect(toIds(watchSnapshot)).to.deep.equal(toIds(getSnapshot)); unsubscribe(); + + await checkOnlineAndOfflineResultsMatch(orderedQuery, ...expectedDocs); }); }); @@ -2546,7 +2554,7 @@ apiDescribe('Database', persistence => { const orderedQuery = query(collectionRef, orderBy(documentId())); const getSnapshot = await getDocsFromServer(orderedQuery); - expect(toIds(getSnapshot)).to.deep.equal([ + const expectedDocs = [ 'Sierpiński', 'Łukasiewicz', '岩澤', @@ -2554,7 +2562,8 @@ apiDescribe('Database', persistence => { 'P', '🄟', '🐵' - ]); + ]; + expect(toIds(getSnapshot)).to.deep.equal(expectedDocs); const storeEvent = new EventsAccumulator(); const unsubscribe = onSnapshot(orderedQuery, storeEvent.storeEvent); @@ -2562,7 +2571,52 @@ apiDescribe('Database', persistence => { expect(toIds(watchSnapshot)).to.deep.equal(toIds(getSnapshot)); unsubscribe(); + + await checkOnlineAndOfflineResultsMatch(orderedQuery, ...expectedDocs); }); }); + + // eslint-disable-next-line no-restricted-properties + (persistence.storage === 'indexeddb' ? it.skip : it)( + 'snapshot listener sorts unicode strings in document key the same as server with persistence', + async () => { + const testDocs = { + 'Łukasiewicz': { value: true }, + 'Sierpiński': { value: true }, + '岩澤': { value: true }, + '🄟': { value: true }, + 'P': { value: true }, + '︒': { value: true }, + '🐵': { value: true } + }; + + return withTestCollection( + persistence, + testDocs, + async collectionRef => { + const orderedQuery = query(collectionRef, orderBy('value')); + + const getSnapshot = await getDocsFromServer(orderedQuery); + expect(toIds(getSnapshot)).to.deep.equal([ + 'Sierpiński', + 'Łukasiewicz', + '岩澤', + '︒', + 'P', + '🄟', + '🐵' + ]); + + const storeEvent = new EventsAccumulator(); + const unsubscribe = onSnapshot(orderedQuery, storeEvent.storeEvent); + const watchSnapshot = await storeEvent.awaitEvent(); + // TODO: IndexedDB sorts string lexicographically, and misses the document with ID '🄟','🐵' + expect(toIds(watchSnapshot)).to.deep.equal(toIds(getSnapshot)); + + unsubscribe(); + } + ); + } + ); }); }); From 5903bbb373663a9ee29ac07ed27e75bf77c226b3 Mon Sep 17 00:00:00 2001 From: milaGGL <107142260+milaGGL@users.noreply.github.com> Date: Wed, 15 Jan 2025 15:15:15 -0500 Subject: [PATCH 10/13] add changeset --- .changeset/spotty-trainers-lay.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/spotty-trainers-lay.md diff --git a/.changeset/spotty-trainers-lay.md b/.changeset/spotty-trainers-lay.md new file mode 100644 index 00000000000..64c30a73e76 --- /dev/null +++ b/.changeset/spotty-trainers-lay.md @@ -0,0 +1,6 @@ +--- +'@firebase/firestore': patch +'firebase': patch +--- + +Fixed a server and sdk mismatch in unicode string sorting. From 2602af4a3fc98c815ea4a47768f3e338d3659e49 Mon Sep 17 00:00:00 2001 From: milaGGL <107142260+milaGGL@users.noreply.github.com> Date: Tue, 4 Feb 2025 16:09:56 -0500 Subject: [PATCH 11/13] Update index.md --- docs-devsite/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs-devsite/index.md b/docs-devsite/index.md index 36e55d452a6..7b2eb7a027c 100644 --- a/docs-devsite/index.md +++ b/docs-devsite/index.md @@ -28,3 +28,4 @@ https://github.com/firebase/firebase-js-sdk | [@firebase/remote-config](./remote-config.md#remote-config_package) | The Firebase Remote Config Web SDK. This SDK does not work in a Node.js environment. | | [@firebase/storage](./storage.md#storage_package) | Cloud Storage for Firebase | | [@firebase/vertexai](./vertexai.md#vertexai_package) | The Vertex AI in Firebase Web SDK. | + \ No newline at end of file From cf9d54a484ffda77c9885129775c4c79274dce96 Mon Sep 17 00:00:00 2001 From: milaGGL <107142260+milaGGL@users.noreply.github.com> Date: Tue, 4 Feb 2025 16:10:31 -0500 Subject: [PATCH 12/13] Update index.md --- docs-devsite/index.md | 1 - 1 file changed, 1 deletion(-) diff --git a/docs-devsite/index.md b/docs-devsite/index.md index 7b2eb7a027c..36e55d452a6 100644 --- a/docs-devsite/index.md +++ b/docs-devsite/index.md @@ -28,4 +28,3 @@ https://github.com/firebase/firebase-js-sdk | [@firebase/remote-config](./remote-config.md#remote-config_package) | The Firebase Remote Config Web SDK. This SDK does not work in a Node.js environment. | | [@firebase/storage](./storage.md#storage_package) | Cloud Storage for Firebase | | [@firebase/vertexai](./vertexai.md#vertexai_package) | The Vertex AI in Firebase Web SDK. | - \ No newline at end of file From 02a470b93356d67a72d9257688844ce1b1dcacb0 Mon Sep 17 00:00:00 2001 From: milaGGL <107142260+milaGGL@users.noreply.github.com> Date: Tue, 4 Feb 2025 16:15:17 -0500 Subject: [PATCH 13/13] Update index.md --- docs-devsite/index.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs-devsite/index.md b/docs-devsite/index.md index 36e55d452a6..82fdb36f076 100644 --- a/docs-devsite/index.md +++ b/docs-devsite/index.md @@ -28,3 +28,4 @@ https://github.com/firebase/firebase-js-sdk | [@firebase/remote-config](./remote-config.md#remote-config_package) | The Firebase Remote Config Web SDK. This SDK does not work in a Node.js environment. | | [@firebase/storage](./storage.md#storage_package) | Cloud Storage for Firebase | | [@firebase/vertexai](./vertexai.md#vertexai_package) | The Vertex AI in Firebase Web SDK. | +