Skip to content

Commit

Permalink
fix: ensure classic computed chains support (#8432) (#8433)
Browse files Browse the repository at this point in the history
  • Loading branch information
runspired authored Feb 27, 2023
1 parent dae9d75 commit d305a52
Show file tree
Hide file tree
Showing 9 changed files with 303 additions and 15 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ npm-debug.log*
testem.log
yarn-error.log
.broccoli-cache
tsconfig.tsbuildinfo

# Ignore artifacts of publishing
*.tgz
Expand Down
12 changes: 10 additions & 2 deletions packages/model/addon/-private/many-array.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@ import { assert, deprecate } from '@ember/debug';

import { DEPRECATE_PROMISE_PROXIES } from '@ember-data/private-build-infra/deprecations';
import type Store from '@ember-data/store';
import { IDENTIFIER_ARRAY_TAG, MUTATE, RecordArray, recordIdentifierFor, SOURCE } from '@ember-data/store/-private';
import {
IDENTIFIER_ARRAY_TAG,
MUTATE,
notifyArray,
RecordArray,
recordIdentifierFor,
SOURCE,
} from '@ember-data/store/-private';
import type ShimModelClass from '@ember-data/store/-private/legacy-model-support/shim-model-class';
import { IdentifierArrayCreateOptions } from '@ember-data/store/-private/record-arrays/identifier-array';
import type { CreateRecordProperties } from '@ember-data/store/-private/store-service';
Expand Down Expand Up @@ -271,8 +278,9 @@ export default class RelatedCollection extends RecordArray {

notify() {
const tag = this[IDENTIFIER_ARRAY_TAG];
tag.ref = null;
tag.shouldReset = true;
// @ts-expect-error
notifyArray(this);
}

/**
Expand Down
3 changes: 3 additions & 0 deletions packages/model/addon/-private/record-state.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ class Tag {
this.rev = 1;
this.isDirty = true;
this.value = undefined;
/*
* whether this was part of a transaction when mutated
*/
this.t = false;
}
@tracked ref = null;
Expand Down
2 changes: 1 addition & 1 deletion packages/private-build-infra/addon/current-deprecations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,6 @@ export default {
DEPRECATE_A_USAGE: '4.7',
DEPRECATE_PROMISE_PROXIES: '4.7',
DEPRECATE_ARRAY_LIKE: '4.7',
DEPRECATE_COMPUTED_CHAINS: '4.7',
DEPRECATE_COMPUTED_CHAINS: '5.0',
DEPRECATE_NON_EXPLICIT_POLYMORPHISM: '4.7',
};
1 change: 1 addition & 0 deletions packages/store/addon/-private/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export {
default as RecordArray,
default as IdentifierArray,
Collection as AdapterPopulatedRecordArray,
notifyArray,
SOURCE,
MUTATE,
IDENTIFIER_ARRAY_TAG,
Expand Down
13 changes: 8 additions & 5 deletions packages/store/addon/-private/managers/record-array-manager.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
@module @ember-data/store
*/
import { addToTransaction } from '@ember-data/tracking/-private';
import { addTransactionCB } from '@ember-data/tracking/-private';
import type { CollectionResourceDocument } from '@ember-data/types/q/ember-data-json-api';
import type { StableRecordIdentifier } from '@ember-data/types/q/identifier';
import type { Dict } from '@ember-data/types/q/utils';
Expand All @@ -10,6 +10,8 @@ import IdentifierArray, {
Collection,
CollectionCreateOptions,
IDENTIFIER_ARRAY_TAG,
NOTIFY,
notifyArray,
SOURCE,
} from '../record-arrays/identifier-array';
import type Store from '../store-service';
Expand Down Expand Up @@ -175,9 +177,9 @@ class RecordArrayManager {
let tag = array[IDENTIFIER_ARRAY_TAG];
if (!tag.shouldReset) {
tag.shouldReset = true;
addToTransaction(tag);
} else if (delta > 0 && tag.t) {
addToTransaction(tag);
addTransactionCB(array[NOTIFY]);
} else if (delta > 0 && !tag.t) {
addTransactionCB(array[NOTIFY]);
}
}

Expand Down Expand Up @@ -244,7 +246,8 @@ class RecordArrayManager {
const old = source.slice();
source.length = 0;
fastPush(source, identifiers);
array[IDENTIFIER_ARRAY_TAG].ref = null;

notifyArray(array);
array.meta = payload.meta || null;
array.links = payload.links || null;
array.isLoaded = true;
Expand Down
54 changes: 47 additions & 7 deletions packages/store/addon/-private/record-arrays/identifier-array.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
/**
@module @ember-data/store
*/
// @ts-expect-error
import { tagForProperty } from '@ember/-internals/metal';
import { assert, deprecate } from '@ember/debug';
import { get, set } from '@ember/object';
import { dependentKeyCompat } from '@ember/object/compat';
import { compare } from '@ember/utils';
import { DEBUG } from '@glimmer/env';
import { tracked } from '@glimmer/tracking';
// @ts-expect-error
import { dirtyTag } from '@glimmer/validator';
import Ember from 'ember';

import {
DEPRECATE_A_USAGE,
DEPRECATE_ARRAY_LIKE,
DEPRECATE_COMPUTED_CHAINS,
DEPRECATE_PROMISE_PROXIES,
DEPRECATE_SNAPSHOT_MODEL_CLASS_ACCESS,
} from '@ember-data/private-build-infra/deprecations';
Expand Down Expand Up @@ -63,6 +68,18 @@ function isArraySetter(prop: KeyType): boolean {
export const IDENTIFIER_ARRAY_TAG = Symbol('#tag');
export const SOURCE = Symbol('#source');
export const MUTATE = Symbol('#update');
export const NOTIFY = Symbol('#notify');

export function notifyArray(arr: IdentifierArray) {
arr[IDENTIFIER_ARRAY_TAG].ref = null;

if (DEPRECATE_COMPUTED_CHAINS) {
// eslint-disable-next-line
dirtyTag(tagForProperty(arr, 'length'));
// eslint-disable-next-line
dirtyTag(tagForProperty(arr, '[]'));
}
}

function convertToInt(prop: KeyType): number | null {
if (typeof prop === 'symbol') return null;
Expand All @@ -76,8 +93,16 @@ function convertToInt(prop: KeyType): number | null {

class Tag {
@tracked ref = null;
shouldReset: boolean = false;
t = false;
declare shouldReset: boolean;
/*
* whether this was part of a transaction when last mutated
*/
declare t: boolean;

constructor() {
this.shouldReset = false;
this.t = false;
}
}

type ProxiedMethod = (...args: unknown[]) => unknown;
Expand Down Expand Up @@ -127,11 +152,9 @@ interface PrivateState {
@class RecordArray
@public
*/

interface IdentifierArray {
interface IdentifierArray extends Omit<Array<RecordInstance>, '[]'> {
[MUTATE]?(prop: string, args: unknown[], result?: unknown): void;
}
interface IdentifierArray extends Array<RecordInstance> {}
class IdentifierArray {
declare DEPRECATED_CLASS_NAME: string;
/**
Expand All @@ -155,6 +178,9 @@ class IdentifierArray {

[IDENTIFIER_ARRAY_TAG] = new Tag();
[SOURCE]: StableRecordIdentifier[];
[NOTIFY]() {
notifyArray(this);
}

declare links: Links | PaginationLinks | null;
declare meta: Dict<unknown> | null;
Expand Down Expand Up @@ -183,7 +209,7 @@ class IdentifierArray {
// changing the reference breaks the Proxy
// this[SOURCE] = [];
this[SOURCE].length = 0;
this[IDENTIFIER_ARRAY_TAG].ref = null;
this[NOTIFY]();
this.isDestroyed = true;
}

Expand All @@ -196,6 +222,14 @@ class IdentifierArray {
this[SOURCE].length = value;
}

// here to support computed chains
// and {{#each}}
get '[]'() {
if (DEPRECATE_COMPUTED_CHAINS) {
return this;
}
}

constructor(options: IdentifierArrayCreateOptions) {
// eslint-disable-next-line @typescript-eslint/no-this-alias
let self = this;
Expand Down Expand Up @@ -296,6 +330,10 @@ class IdentifierArray {
}
}

if (prop === NOTIFY || prop === IDENTIFIER_ARRAY_TAG || prop === SOURCE) {
return self[prop];
}

let fn = boundFns.get(prop);
if (fn) return fn;

Expand Down Expand Up @@ -403,6 +441,8 @@ class IdentifierArray {
};
}

this[NOTIFY] = this[NOTIFY].bind(proxy);

return proxy;
}

Expand Down Expand Up @@ -544,7 +584,7 @@ export class Collection extends IdentifierArray {
Collection.prototype.query = null;

// Ensure instanceof works correctly
// Object.setPrototypeOf(IdentifierArray.prototype, Array.prototype);
//Object.setPrototypeOf(IdentifierArray.prototype, Array.prototype);

if (DEPRECATE_ARRAY_LIKE) {
IdentifierArray.prototype.DEPRECATED_CLASS_NAME = 'RecordArray';
Expand Down
2 changes: 2 additions & 0 deletions packages/tracking/src/-private.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ function flushTransaction() {
cb();
});
transaction.props.forEach((obj: Tag) => {
// mark this mutation as part of a transaction
obj.t = true;
obj.ref = null;
});
Expand All @@ -67,6 +68,7 @@ async function untrack() {
cb();
});
transaction.props.forEach((obj: Tag) => {
// mark this mutation as part of a transaction
obj.t = true;
obj.ref = null;
});
Expand Down
Loading

0 comments on commit d305a52

Please sign in to comment.