Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix/no structuredClone on react native #5321

Merged
merged 2 commits into from
Nov 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ examples/supabase/
examples/vite-vanilla-ts
node_modules
docs
docs-src/files/logo/js.build.js
docs-src/static/files/logo/js.build.js
docs-src/_book/
docs-src/build/
1 change: 1 addition & 0 deletions docs-src/docs/releases/15.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ In the past we used gitbook which is no longer maintained and had some major iss
- FIX PushModifier applied to pre-change legacy document, resulting in old document sent to endpoint [#5256](https://github.com/pubkey/rxdb/issues/5256)
- [Attachment compression](../rx-attachment.md#attachment-compression) is now using the native `Compression Streams API`.
- FIX [#5311](https://github.com/pubkey/rxdb/issues/5311) URL.createObjectURL is not a function in a browser plugin environment(background.js)
- FIX `structuredClone` not available in ReactNative [#5046](https://github.com/pubkey/rxdb/issues/5046#issuecomment-1827374498)
- The following things moved out of beta:
- [Firestore replication](../replication-firestore.md)
- [WebRTC replication](../replication-webrtc.md)
Expand Down
18 changes: 9 additions & 9 deletions src/change-event-buffer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@ import type {
RxCollection
} from './types/index.d.ts';

export class ChangeEventBuffer {
export class ChangeEventBuffer<RxDocType> {
private subs: Subscription[] = [];
public limit: number = 100;
public counter: number = 0;
private eventCounterMap: WeakMap<
RxChangeEvent<any>, number
RxChangeEvent<RxDocType>, number
> = new WeakMap();

/**
* array with changeEvents
* starts with oldest known event, ends with newest
*/
public buffer: RxChangeEvent<any>[] = [];
public buffer: RxChangeEvent<RxDocType>[] = [];

constructor(
public collection: RxCollection
Expand All @@ -34,7 +34,7 @@ export class ChangeEventBuffer {
);
}

_handleChangeEvent(changeEvent: RxChangeEvent<any>) {
_handleChangeEvent(changeEvent: RxChangeEvent<RxDocType>) {
this.counter++;
this.buffer.push(changeEvent);
this.eventCounterMap.set(changeEvent, this.counter);
Expand Down Expand Up @@ -64,7 +64,7 @@ export class ChangeEventBuffer {
* get all changeEvents which came in later than the pointer-event
* @return array with change-events. If null, pointer out of bounds
*/
getFrom(pointer: number): RxChangeEvent<any>[] | null {
getFrom(pointer: number): RxChangeEvent<RxDocType>[] | null {
const ret = [];
let currentIndex = this.getArrayIndexByPointer(pointer);
if (currentIndex === null) // out of bounds
Expand Down Expand Up @@ -95,7 +95,7 @@ export class ChangeEventBuffer {
* only the last operation has to be checked to calculate the new state
* this function reduces the events to the last ChangeEvent of each doc
*/
reduceByLastOfDoc(changeEvents: RxChangeEvent<any>[]): RxChangeEvent<any>[] {
reduceByLastOfDoc(changeEvents: RxChangeEvent<RxDocType>[]): RxChangeEvent<RxDocType>[] {
return changeEvents.slice(0);
// TODO the old implementation was wrong
// because it did not correctly reassigned the previousData of the changeevents
Expand All @@ -112,8 +112,8 @@ export class ChangeEventBuffer {
}
}

export function createChangeEventBuffer(
collection: RxCollection<any, any>
export function createChangeEventBuffer<RxdocType>(
collection: RxCollection<RxdocType, any>
) {
return new ChangeEventBuffer(collection);
return new ChangeEventBuffer<RxdocType>(collection);
}
1 change: 1 addition & 0 deletions src/event-reduce.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ export function calculateNewResults<RxDocumentType>(
const eventReduceEvents: ChangeEvent<RxDocumentType>[] = rxChangeEvents
.map(cE => rxChangeEventToEventReduceChangeEvent(cE))
.filter(arrayFilterNotEmpty);

const foundNonOptimizeable = eventReduceEvents.find(eventReduceEvent => {
const stateResolveFunctionInput: StateResolveFunctionInput<RxDocumentType> = {
queryParams,
Expand Down
4 changes: 2 additions & 2 deletions src/rx-collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ export class RxCollectionBase<
public _queryCache: QueryCache = createQueryCache();
public $: Observable<RxChangeEvent<RxDocumentType>> = {} as any;
public checkpoint$: Observable<any> = {} as any;
public _changeEventBuffer: ChangeEventBuffer = {} as ChangeEventBuffer;
public _changeEventBuffer: ChangeEventBuffer<RxDocumentType> = {} as ChangeEventBuffer<RxDocumentType>;



Expand Down Expand Up @@ -209,7 +209,7 @@ export class RxCollectionBase<
map(changeEventBulk => changeEventBulk.checkpoint),
);

this._changeEventBuffer = createChangeEventBuffer(this.asRxCollection);
this._changeEventBuffer = createChangeEventBuffer<RxDocumentType>(this.asRxCollection);
this._docCache = new DocumentCache(
this.schema.primaryPath,
this.$.pipe(filter(cE => !cE.isLocal)),
Expand Down
5 changes: 3 additions & 2 deletions src/rx-query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -540,9 +540,10 @@ function __ensureEqual<RxDocType>(rxQuery: RxQueryBase<RxDocType>): Promise<bool
} else {
rxQuery._latestChangeEvent = rxQuery.asRxQuery.collection._changeEventBuffer.counter;

const runChangeEvents: RxChangeEvent<any>[] = rxQuery.asRxQuery.collection
const runChangeEvents: RxChangeEvent<RxDocType>[] = rxQuery.asRxQuery.collection
._changeEventBuffer
.reduceByLastOfDoc(missedChangeEvents);
.reduceByLastOfDoc(missedChangeEvents)
.filter(ev => ev.documentData._meta.lwt > rxQuery._lastExecStart);

if (rxQuery.op === 'count') {
// 'count' query
Expand Down
12 changes: 10 additions & 2 deletions src/rx-storage-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -580,15 +580,23 @@ export function getWrappedStorageInstance<
* Ensure it can be structured cloned
*/
try {
structuredClone(writeRow);
/**
* Notice that structuredClone() is not available
* in ReactNative, so we test for JSON.stringify() instead
* @link https://github.com/pubkey/rxdb/issues/5046#issuecomment-1827374498
*/
if (typeof structuredClone === 'function') {
structuredClone(writeRow);
} else {
JSON.parse(JSON.stringify(writeRow));
}
} catch (err) {
throw newRxError('DOC24', {
collection: storageInstance.collectionName,
document: writeRow.document
});
}


/**
* Ensure that the new revision is higher
* then the previous one
Expand Down
7 changes: 5 additions & 2 deletions test/unit/bug-report.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
} from '../../plugins/core/index.mjs';

describe('bug-report.test.js', () => {
it('should fail because it reproduces the bug', async () => {
it('should fail because it reproduces the bug', async function () {

/**
* If your test should only run in nodejs or only run in the browser,
Expand Down Expand Up @@ -121,11 +121,14 @@ describe('bug-report.test.js', () => {
*/
assert.strictEqual(myDocument.age, 56);


// you can also wait for events
const emitted = [];
const sub = collectionInOtherTab.mycollection
.findOne().$
.subscribe(doc => emitted.push(doc));
.subscribe(doc => {
emitted.push(doc);
});
await AsyncTestUtil.waitUntil(() => emitted.length === 1);

// clean up afterwards
Expand Down