From e31918d942fd13fc7d412ea5c8ed8bffa9ae8672 Mon Sep 17 00:00:00 2001 From: Alexander Cerutti Date: Mon, 25 Oct 2021 01:00:51 +0200 Subject: [PATCH] Refactored FieldsArray to add overrides for shift and unshift and to share code between methods --- src/FieldsArray.ts | 123 ++++++++++++++++++++------------------------- 1 file changed, 55 insertions(+), 68 deletions(-) diff --git a/src/FieldsArray.ts b/src/FieldsArray.ts index de6ae8d..751714f 100644 --- a/src/FieldsArray.ts +++ b/src/FieldsArray.ts @@ -25,64 +25,15 @@ export default class FieldsArray extends Array { this[sharedKeysPoolSymbol] = keysPool; } - /** - * Like `Array.prototype.push` but will alter - * also uniqueKeys set. - */ - - push(...fieldsData: Schemas.Field[]): number { - Utils.assertUnfrozen(this[passInstanceSymbol]); - - const validFields = fieldsData.reduce( - (acc: Schemas.Field[], current: Schemas.Field) => { - try { - Schemas.assertValidity( - Schemas.Field, - current, - Messages.FIELDS.INVALID, - ); - } catch (err) { - console.warn(err); - return acc; - } - - if (this[sharedKeysPoolSymbol].has(current.key)) { - console.warn( - Messages.format( - Messages.FIELDS.REPEATED_KEY, - current.key, - ), - ); - return acc; - } - - this[sharedKeysPoolSymbol].add(current.key); - return [...acc, current]; - }, - [], - ); - - return super.push(...validFields); + push(...items: Schemas.Field[]): number { + const validItems = registerWithValidation(this, ...items); + return super.push(...validItems); } - /** - * Like `Array.prototype.pop`, but will alter - * also uniqueKeys set - */ - pop(): Schemas.Field { - Utils.assertUnfrozen(this[passInstanceSymbol]); - - const element: Schemas.Field = super.pop(); - this[sharedKeysPoolSymbol].delete(element.key); - return element; + return unregisterItems(this, () => super.pop()); } - /** - * Like `Array.prototype.splice` but will alter - * also uniqueKeys set - */ - splice( start: number, deleteCount: number, @@ -90,25 +41,61 @@ export default class FieldsArray extends Array { ): Schemas.Field[] { Utils.assertUnfrozen(this[passInstanceSymbol]); - const removeList = this.slice(start, deleteCount + start); - removeList.forEach((item) => - this[sharedKeysPoolSymbol].delete(item.key), - ); - - let validItems = items ?? []; - - if (validItems.length) { - validItems = Schemas.filterValid(Schemas.Field, items); - - for (let i = 0; i < validItems.length; i++) { - this[sharedKeysPoolSymbol].add(validItems[i].key); - } + for (let i = start; i < start + deleteCount; i++) { + this[sharedKeysPoolSymbol].delete(this[i].key); } + const validItems = registerWithValidation(this, ...items); return super.splice(start, deleteCount, ...validItems); } - get length(): number { - return this.length; + shift() { + return unregisterItems(this, () => super.shift()); + } + + unshift(...items: Schemas.Field[]) { + const validItems = registerWithValidation(this, ...items); + return super.unshift(...validItems); } } + +function registerWithValidation( + instance: InstanceType, + ...items: Schemas.Field[] +) { + Utils.assertUnfrozen(instance[passInstanceSymbol]); + + let validItems: Schemas.Field[] = []; + + for (let i = items.length, field: Schemas.Field; (field = items[--i]); ) { + try { + Schemas.assertValidity( + Schemas.Field, + field, + Messages.FIELDS.INVALID, + ); + + if (instance[sharedKeysPoolSymbol].has(field.key)) { + throw Messages.format(Messages.FIELDS.REPEATED_KEY, field.key); + } + + instance[sharedKeysPoolSymbol].add(field.key); + validItems.push(field); + } catch (err) { + console.warn(err); + } + } + + return validItems; +} + +function unregisterItems( + instance: InstanceType, + removeFn: Function, +) { + Utils.assertUnfrozen(instance[passInstanceSymbol]); + + const element: Schemas.Field = removeFn(); + instance[sharedKeysPoolSymbol].delete(element.key); + return element; +}