diff options
author | bobzel <zzzman@gmail.com> | 2024-05-14 23:15:24 -0400 |
---|---|---|
committer | bobzel <zzzman@gmail.com> | 2024-05-14 23:15:24 -0400 |
commit | 3534aaf88a3c30a474b3b5a5b7f04adfe6f15fac (patch) | |
tree | 47fb7a8671b209bd4d76e0f755a5b035c6936607 /src/fields/List.ts | |
parent | 87bca251d87b5a95da06b2212400ce9427152193 (diff) | |
parent | 5cb7ad90e120123ca572e8ef5b1aa6ca41581134 (diff) |
Merge branch 'restoringEslint' into sarah-ai-visualization
Diffstat (limited to 'src/fields/List.ts')
-rw-r--r-- | src/fields/List.ts | 97 |
1 files changed, 47 insertions, 50 deletions
diff --git a/src/fields/List.ts b/src/fields/List.ts index ec31f7dae..38c47d546 100644 --- a/src/fields/List.ts +++ b/src/fields/List.ts @@ -1,31 +1,28 @@ import { action, computed, makeObservable, observable } from 'mobx'; -import { alias, list, serializable } from 'serializr'; -import { DocServer } from '../client/DocServer'; +import { alias, list as serializrList, serializable } from 'serializr'; import { ScriptingGlobals } from '../client/util/ScriptingGlobals'; import { Deserializable, afterDocDeserialize, autoObject } from '../client/util/SerializationHelper'; -import { Field } from './Doc'; +import { Field, FieldType, StrListCast } from './Doc'; import { FieldTuples, Self, SelfProxy } from './DocSymbols'; import { Copy, FieldChanged, Parent, ToJavascriptString, ToScriptString, ToString } from './FieldSymbols'; -import { ObjectField } from './ObjectField'; +import { ObjGetRefFields, ObjectField } from './ObjectField'; import { ProxyField } from './Proxy'; import { RefField } from './RefField'; -import { listSpec } from './Schema'; -import { Cast } from './Types'; import { containedFieldChangedHandler, deleteProperty, getter, setter } from './util'; -function toObjectField(field: Field) { +function toObjectField(field: FieldType) { return field instanceof RefField ? new ProxyField(field) : field; } -function toRealField(field: Field) { +function toRealField(field: FieldType) { return field instanceof ProxyField ? field.value : field; } -type StoredType<T extends Field> = T extends RefField ? ProxyField<T> : T; +type StoredType<T extends FieldType> = T extends RefField ? ProxyField<T> : T; export const ListFieldName = 'fields'; @Deserializable('list') -class ListImpl<T extends Field> extends ObjectField { +class ListImpl<T extends FieldType> extends ObjectField { static listHandlers: any = { /// Mutator methods copyWithin() { @@ -44,14 +41,14 @@ class ListImpl<T extends Field> extends ObjectField { this[SelfProxy][FieldChanged]?.(); return field; }, - push: action(function (this: ListImpl<any>, ...items: any[]) { - items = items.map(toObjectField); + push: action(function (this: ListImpl<any>, ...itemsIn: any[]) { + const items = itemsIn.map(toObjectField); const list = this[Self]; - const length = list.__fieldTuples.length; + const { length } = list.__fieldTuples; for (let i = 0; i < items.length; i++) { const item = items[i]; - //TODO Error checking to make sure parent doesn't already exist + // TODO Error checking to make sure parent doesn't already exist if (item instanceof ObjectField) { item[Parent] = list; item[FieldChanged] = containedFieldChangedHandler(this[SelfProxy], i + length, item); @@ -77,21 +74,21 @@ class ListImpl<T extends Field> extends ObjectField { this[SelfProxy][FieldChanged]?.(); return res; }, - splice: action(function (this: any, start: number, deleteCount: number, ...items: any[]) { + splice: action(function (this: any, start: number, deleteCount: number, ...itemsIn: any[]) { this[Self].__realFields; // coerce retrieving entire array - items = items.map(toObjectField); + const items = itemsIn.map(toObjectField); const list = this[Self]; const removed = list.__fieldTuples.filter((item: any, i: number) => i >= start && i < start + deleteCount); for (let i = 0; i < items.length; i++) { const item = items[i]; - //TODO Error checking to make sure parent doesn't already exist - //TODO Need to change indices of other fields in array + // TODO Error checking to make sure parent doesn't already exist + // TODO Need to change indices of other fields in array if (item instanceof ObjectField) { item[Parent] = list; item[FieldChanged] = containedFieldChangedHandler(this, i + start, item); } } - let hintArray: { val: any; index: number }[] = []; + const hintArray: { val: any; index: number }[] = []; for (let i = start; i < start + deleteCount; i++) { hintArray.push({ val: list.__fieldTuples[i], index: i }); } @@ -107,13 +104,13 @@ class ListImpl<T extends Field> extends ObjectField { ); return res.map(toRealField); }), - unshift(...items: any[]) { - items = items.map(toObjectField); + unshift(...itemsIn: any[]) { + const items = itemsIn.map(toObjectField); const list = this[Self]; for (let i = 0; i < items.length; i++) { const item = items[i]; - //TODO Error checking to make sure parent doesn't already exist - //TODO Need to change indices of other fields in array + // TODO Error checking to make sure parent doesn't already exist + // TODO Need to change indices of other fields in array if (item instanceof ObjectField) { item[Parent] = list; item[FieldChanged] = containedFieldChangedHandler(this, i, item); @@ -131,9 +128,8 @@ class ListImpl<T extends Field> extends ObjectField { includes(valueToFind: any, fromIndex: number) { if (valueToFind instanceof RefField) { return this[Self].__realFields.includes(valueToFind, fromIndex); - } else { - return this[Self].__fieldTuples.includes(valueToFind, fromIndex); } + return this[Self].__fieldTuples.includes(valueToFind, fromIndex); }, indexOf(valueToFind: any, fromIndex: number) { if (valueToFind instanceof RefField) { @@ -151,9 +147,8 @@ class ListImpl<T extends Field> extends ObjectField { lastIndexOf(valueToFind: any, fromIndex: number) { if (valueToFind instanceof RefField) { return this[Self].__realFields.lastIndexOf(valueToFind, fromIndex); - } else { - return this[Self].__fieldTuples.lastIndexOf(valueToFind, fromIndex); } + return this[Self].__fieldTuples.lastIndexOf(valueToFind, fromIndex); }, slice(begin: number, end: number) { this[Self].__realFields; @@ -226,7 +221,7 @@ class ListImpl<T extends Field> extends ObjectField { }, }; static listGetter(target: any, prop: string | symbol, receiver: any): any { - if (ListImpl.listHandlers.hasOwnProperty(prop)) { + if (Object.prototype.hasOwnProperty.call(ListImpl.listHandlers, prop)) { return ListImpl.listHandlers[prop]; } return getter(target, prop, receiver); @@ -244,7 +239,7 @@ class ListImpl<T extends Field> extends ObjectField { getOwnPropertyDescriptor: (target, prop) => { if (prop in target[FieldTuples]) { return { - configurable: true, //TODO Should configurable be true? + configurable: true, // TODO Should configurable be true? enumerable: true, }; } @@ -255,11 +250,13 @@ class ListImpl<T extends Field> extends ObjectField { throw new Error("Currently properties can't be defined on documents using Object.defineProperty"); }, }); - this[SelfProxy] = list as any as List<Field>; // bcz: ugh .. don't know how to convince typesecript that list is a List + // eslint-disable-next-line no-use-before-define + this[SelfProxy] = list as any as List<FieldType>; // bcz: ugh .. don't know how to convince typesecript that list is a List if (fields) { this[SelfProxy].push(...fields); } - return list; + // eslint-disable-next-line no-constructor-return + return list; // need to return the proxy here, otherwise we don't get any of our list handler functions } [key: number]: T | (T extends RefField ? Promise<T> : never); @@ -271,7 +268,7 @@ class ListImpl<T extends Field> extends ObjectField { // if we find any ProxyFields that don't have a current value, then // start the server request for all of them if (unrequested.length) { - const batchPromise = DocServer.GetRefFields(unrequested.map(p => p.fieldId)); + const batchPromise = ObjGetRefFields(unrequested.map(p => p.fieldId)); // as soon as we get the fields from the server, set all the list values in one // action to generate one React dom update. const allSetPromise = batchPromise.then(action(pfields => unrequested.map(toReq => toReq.setValue(pfields[toReq.fieldId])))); @@ -282,20 +279,20 @@ class ListImpl<T extends Field> extends ObjectField { return this[FieldTuples].map(toRealField); } - @serializable(alias(ListFieldName, list(autoObject(), { afterDeserialize: afterDocDeserialize }))) + @serializable(alias(ListFieldName, serializrList(autoObject(), { afterDeserialize: afterDocDeserialize }))) private get __fieldTuples() { return this[FieldTuples]; } private set __fieldTuples(value) { this[FieldTuples] = value; - for (const key in value) { - const item = value[key]; + Object.keys(value).forEach(key => { + const item = value[Number(key)]; if (item instanceof ObjectField) { item[Parent] = this[Self]; item[FieldChanged] = containedFieldChangedHandler(this[SelfProxy], Number(key), item); } - } + }); } [Copy]() { @@ -308,24 +305,24 @@ class ListImpl<T extends Field> extends ObjectField { @observable private [FieldTuples]: StoredType<T>[] = []; private [Self] = this; - private [SelfProxy]: List<Field>; // also used in utils.ts even though it won't be found using find all references + // eslint-disable-next-line no-use-before-define + private [SelfProxy]: List<FieldType>; // also used in utils.ts even though it won't be found using find all references - [ToJavascriptString]() { - return `[${(this as any).map((field: any) => Field.toScriptString(field))}]`; - } - [ToScriptString]() { - return `new List([${(this as any).map((field: any) => Field.toScriptString(field))}])`; - } - [ToString]() { - return `[${(this as any).map((field: any) => Field.toString(field))}]`; - } + [ToScriptString]() { return `new List(${this[ToJavascriptString]()})`; } // prettier-ignore + [ToJavascriptString]() { return `[${(this as any).map((field: any) => Field.toScriptString(field))}]`; } // prettier-ignore + [ToString]() { return `[${(this as any).map((field: any) => Field.toString(field))}]`; } // prettier-ignore } -export type List<T extends Field> = ListImpl<T> & (T | (T extends RefField ? Promise<T> : never))[]; -export const List: { new <T extends Field>(fields?: T[]): List<T> } = ListImpl as any; + +// declare List as a type so you can use it in type declarations, e.g., { l: List, ...} +export type List<T extends FieldType> = ListImpl<T> & (T | (T extends RefField ? Promise<T> : never))[]; +// decalre List as a value so you can invoke 'new' on it, e.g., new List<Doc>() +// eslint-disable-next-line no-redeclare +export const List: { new <T extends FieldType>(fields?: T[]): List<T> } = ListImpl as any; ScriptingGlobals.add('List', List); +// eslint-disable-next-line prefer-arrow-callback ScriptingGlobals.add(function compareLists(l1: any, l2: any) { - const L1 = Cast(l1, listSpec('string'), []); - const L2 = Cast(l2, listSpec('string'), []); + const L1 = StrListCast(l1); + const L2 = StrListCast(l2); return !L1 && !L2 ? true : L1 && L2 && L1.length === L2.length && L2.reduce((p, v) => p && L1.includes(v), true); }, 'compare two lists'); |