@esportsplus/reactivity 0.4.1 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
- import { Infer, Prettify } from '../types.js';
1
+ import { Infer } from '../types.js';
2
2
  import { Listener, Options, ReactiveObject, Signal } from '../types.js';
3
- type API<T> = Prettify<Infer<T>[] & ReturnType<typeof methods<T>>>;
3
+ type API<T> = Infer<T>[] & ReactiveArray<T>;
4
4
  type Events<T> = {
5
5
  pop: {
6
6
  item: Item<T>;
@@ -27,19 +27,21 @@ type Events<T> = {
27
27
  };
28
28
  };
29
29
  type Item<T> = T extends Record<PropertyKey, unknown> ? ReactiveObject<T> : Signal<T>;
30
- declare class ReactiveArray<T> extends Array<Item<T>> {
30
+ declare class ReactiveArray<T> {
31
+ private data;
31
32
  private options;
32
33
  private proxy;
33
34
  private signal;
34
35
  constructor(data: Item<T>[], proxy: API<T>, options?: Options);
36
+ get length(): number;
35
37
  set length(n: number);
36
38
  at(i: number): any;
37
- dispatch<E extends keyof Events<T>>(event: E, data?: Events<T>[E]): void;
39
+ dispatch<E extends keyof Events<unknown>>(event: E, data?: Events<T>[E]): void;
38
40
  dispose(): void;
39
- indexOf(value: T): number;
41
+ indexOf(value: T, fromIndex?: number): number;
40
42
  map<U>(fn: (this: API<T>, value: T, i: number) => U, i?: number, n?: number): U[];
41
- on<E extends keyof Events<T>>(event: E, listener: Listener<Events<T>[E]>): void;
42
- once<E extends keyof Events<T>>(event: E, listener: Listener<Events<T>[E]>): void;
43
+ on<E extends keyof Events<unknown>>(event: E, listener: Listener<Events<T>[E]>): void;
44
+ once<E extends keyof Events<unknown>>(event: E, listener: Listener<Events<T>[E]>): void;
43
45
  pop(): Item<T> | undefined;
44
46
  push(...input: T[]): number;
45
47
  reverse(): this;
@@ -48,185 +50,6 @@ declare class ReactiveArray<T> extends Array<Item<T>> {
48
50
  splice(start: number, deleteCount?: number, ...input: T[]): Item<T>[];
49
51
  unshift(...input: T[]): number;
50
52
  }
51
- declare function methods<T>(a: ReactiveArray<T>): Prettify<{
52
- get constructor(): typeof a['constructor'];
53
- get length(): number;
54
- set length(n: number);
55
- } & Pick<typeof a, 'at' | 'dispatch' | 'dispose' | 'indexOf' | 'map' | 'on' | 'once' | 'pop' | 'push' | 'reverse' | 'shift' | 'sort' | 'splice' | 'unshift'>>;
56
- declare const _default: <T>(input: T[], options?: Options) => {
57
- [x: number]: Infer<T>;
58
- length: number;
59
- toString: () => string;
60
- toLocaleString: {
61
- (): string;
62
- (locales: string | string[], options?: Intl.NumberFormatOptions & Intl.DateTimeFormatOptions): string;
63
- };
64
- pop: (() => Infer<T> | undefined) & (() => Item<T> | undefined);
65
- push: ((...items: Infer<T>[]) => number) & ((...input: T[]) => number);
66
- concat: {
67
- (...items: ConcatArray<Infer<T>>[]): Infer<T>[];
68
- (...items: (Infer<T> | ConcatArray<Infer<T>>)[]): Infer<T>[];
69
- };
70
- join: (separator?: string) => string;
71
- reverse: (() => Infer<T>[]) & (() => ReactiveArray<T>);
72
- shift: (() => Infer<T> | undefined) & (() => Item<T> | undefined);
73
- slice: (start?: number, end?: number) => Infer<T>[];
74
- sort: ((compareFn?: ((a: Infer<T>, b: Infer<T>) => number) | undefined) => Infer<T>[] & {
75
- readonly constructor: Function;
76
- length: number;
77
- dispatch: <E extends keyof Events<T_1>>(event: E, data?: Events<T>[E] | undefined) => void;
78
- dispose: () => void;
79
- on: <E extends keyof Events<T_1>>(event: E, listener: Listener<Events<T>[E]>) => void;
80
- once: <E extends keyof Events<T_1>>(event: E, listener: Listener<Events<T>[E]>) => void;
81
- at: (i: number) => any;
82
- indexOf: (value: T) => number;
83
- map: <U>(fn: (this: any, value: T, i: number) => U, i?: number, n?: number) => U[];
84
- pop: () => Item<T> | undefined;
85
- push: (...input: T[]) => number;
86
- reverse: () => ReactiveArray<T>;
87
- shift: () => Item<T> | undefined;
88
- sort: (fn: (a: T, b: T) => number) => ReactiveArray<T>;
89
- splice: (start: number, deleteCount?: number, ...input: T[]) => Item<T>[];
90
- unshift: (...input: T[]) => number;
91
- }) & ((fn: (a: T, b: T) => number) => ReactiveArray<T>);
92
- splice: {
93
- (start: number, deleteCount?: number): Infer<T>[];
94
- (start: number, deleteCount: number, ...items: Infer<T>[]): Infer<T>[];
95
- } & ((start: number, deleteCount?: number, ...input: T[]) => Item<T>[]);
96
- unshift: ((...items: Infer<T>[]) => number) & ((...input: T[]) => number);
97
- indexOf: ((searchElement: Infer<T>, fromIndex?: number) => number) & ((value: T) => number);
98
- lastIndexOf: (searchElement: Infer<T>, fromIndex?: number) => number;
99
- every: {
100
- <S extends Infer<T>>(predicate: (value: Infer<T>, index: number, array: Infer<T>[]) => value is S, thisArg?: any): this is S[];
101
- (predicate: (value: Infer<T>, index: number, array: Infer<T>[]) => unknown, thisArg?: any): boolean;
102
- };
103
- some: (predicate: (value: Infer<T>, index: number, array: Infer<T>[]) => unknown, thisArg?: any) => boolean;
104
- forEach: (callbackfn: (value: Infer<T>, index: number, array: Infer<T>[]) => void, thisArg?: any) => void;
105
- map: (<U>(callbackfn: (value: Infer<T>, index: number, array: Infer<T>[]) => U, thisArg?: any) => U[]) & (<U>(fn: (this: any, value: T, i: number) => U, i?: number, n?: number) => U[]);
106
- filter: {
107
- <S extends Infer<T>>(predicate: (value: Infer<T>, index: number, array: Infer<T>[]) => value is S, thisArg?: any): S[];
108
- (predicate: (value: Infer<T>, index: number, array: Infer<T>[]) => unknown, thisArg?: any): Infer<T>[];
109
- };
110
- reduce: {
111
- (callbackfn: (previousValue: Infer<T>, currentValue: Infer<T>, currentIndex: number, array: Infer<T>[]) => Infer<T>): Infer<T>;
112
- (callbackfn: (previousValue: Infer<T>, currentValue: Infer<T>, currentIndex: number, array: Infer<T>[]) => Infer<T>, initialValue: Infer<T>): Infer<T>;
113
- <U>(callbackfn: (previousValue: U, currentValue: Infer<T>, currentIndex: number, array: Infer<T>[]) => U, initialValue: U): U;
114
- };
115
- reduceRight: {
116
- (callbackfn: (previousValue: Infer<T>, currentValue: Infer<T>, currentIndex: number, array: Infer<T>[]) => Infer<T>): Infer<T>;
117
- (callbackfn: (previousValue: Infer<T>, currentValue: Infer<T>, currentIndex: number, array: Infer<T>[]) => Infer<T>, initialValue: Infer<T>): Infer<T>;
118
- <U>(callbackfn: (previousValue: U, currentValue: Infer<T>, currentIndex: number, array: Infer<T>[]) => U, initialValue: U): U;
119
- };
120
- find: {
121
- <S extends Infer<T>>(predicate: (value: Infer<T>, index: number, obj: Infer<T>[]) => value is S, thisArg?: any): S | undefined;
122
- (predicate: (value: Infer<T>, index: number, obj: Infer<T>[]) => unknown, thisArg?: any): Infer<T> | undefined;
123
- };
124
- findIndex: (predicate: (value: Infer<T>, index: number, obj: Infer<T>[]) => unknown, thisArg?: any) => number;
125
- fill: (value: Infer<T>, start?: number, end?: number) => Infer<T>[] & {
126
- readonly constructor: Function;
127
- length: number;
128
- dispatch: <E extends keyof Events<T_1>>(event: E, data?: Events<T>[E] | undefined) => void;
129
- dispose: () => void;
130
- on: <E extends keyof Events<T_1>>(event: E, listener: Listener<Events<T>[E]>) => void;
131
- once: <E extends keyof Events<T_1>>(event: E, listener: Listener<Events<T>[E]>) => void;
132
- at: (i: number) => any;
133
- indexOf: (value: T) => number;
134
- map: <U>(fn: (this: any, value: T, i: number) => U, i?: number, n?: number) => U[];
135
- pop: () => Item<T> | undefined;
136
- push: (...input: T[]) => number;
137
- reverse: () => ReactiveArray<T>;
138
- shift: () => Item<T> | undefined;
139
- sort: (fn: (a: T, b: T) => number) => ReactiveArray<T>;
140
- splice: (start: number, deleteCount?: number, ...input: T[]) => Item<T>[];
141
- unshift: (...input: T[]) => number;
142
- };
143
- copyWithin: (target: number, start: number, end?: number) => Infer<T>[] & {
144
- readonly constructor: Function;
145
- length: number;
146
- dispatch: <E extends keyof Events<T_1>>(event: E, data?: Events<T>[E] | undefined) => void;
147
- dispose: () => void;
148
- on: <E extends keyof Events<T_1>>(event: E, listener: Listener<Events<T>[E]>) => void;
149
- once: <E extends keyof Events<T_1>>(event: E, listener: Listener<Events<T>[E]>) => void;
150
- at: (i: number) => any;
151
- indexOf: (value: T) => number;
152
- map: <U>(fn: (this: any, value: T, i: number) => U, i?: number, n?: number) => U[];
153
- pop: () => Item<T> | undefined;
154
- push: (...input: T[]) => number;
155
- reverse: () => ReactiveArray<T>;
156
- shift: () => Item<T> | undefined;
157
- sort: (fn: (a: T, b: T) => number) => ReactiveArray<T>;
158
- splice: (start: number, deleteCount?: number, ...input: T[]) => Item<T>[];
159
- unshift: (...input: T[]) => number;
160
- };
161
- entries: () => ArrayIterator<[number, Infer<T>]>;
162
- keys: () => ArrayIterator<number>;
163
- values: () => ArrayIterator<Infer<T>>;
164
- includes: (searchElement: Infer<T>, fromIndex?: number) => boolean;
165
- flatMap: <U, This = undefined>(callback: (this: This, value: Infer<T>, index: number, array: Infer<T>[]) => U | readonly U[], thisArg?: This | undefined) => U[];
166
- flat: <A, D extends number = 1>(this: A, depth?: D | undefined) => FlatArray<A, D>[];
167
- at: ((index: number) => Infer<T> | undefined) & ((i: number) => any);
168
- findLast: {
169
- <S extends Infer<T>>(predicate: (value: Infer<T>, index: number, array: Infer<T>[]) => value is S, thisArg?: any): S | undefined;
170
- (predicate: (value: Infer<T>, index: number, array: Infer<T>[]) => unknown, thisArg?: any): Infer<T> | undefined;
171
- };
172
- findLastIndex: (predicate: (value: Infer<T>, index: number, array: Infer<T>[]) => unknown, thisArg?: any) => number;
173
- toReversed: () => Infer<T>[];
174
- toSorted: (compareFn?: ((a: Infer<T>, b: Infer<T>) => number) | undefined) => Infer<T>[];
175
- toSpliced: {
176
- (start: number, deleteCount: number, ...items: Infer<T>[]): Infer<T>[];
177
- (start: number, deleteCount?: number): Infer<T>[];
178
- };
179
- with: (index: number, value: Infer<T>) => Infer<T>[];
180
- [Symbol.iterator]: () => ArrayIterator<Infer<T>>;
181
- readonly [Symbol.unscopables]: {
182
- [x: number]: boolean | undefined;
183
- length?: boolean | undefined;
184
- toString?: boolean | undefined;
185
- toLocaleString?: boolean | undefined;
186
- pop?: boolean | undefined;
187
- push?: boolean | undefined;
188
- concat?: boolean | undefined;
189
- join?: boolean | undefined;
190
- reverse?: boolean | undefined;
191
- shift?: boolean | undefined;
192
- slice?: boolean | undefined;
193
- sort?: boolean | undefined;
194
- splice?: boolean | undefined;
195
- unshift?: boolean | undefined;
196
- indexOf?: boolean | undefined;
197
- lastIndexOf?: boolean | undefined;
198
- every?: boolean | undefined;
199
- some?: boolean | undefined;
200
- forEach?: boolean | undefined;
201
- map?: boolean | undefined;
202
- filter?: boolean | undefined;
203
- reduce?: boolean | undefined;
204
- reduceRight?: boolean | undefined;
205
- find?: boolean | undefined;
206
- findIndex?: boolean | undefined;
207
- fill?: boolean | undefined;
208
- copyWithin?: boolean | undefined;
209
- entries?: boolean | undefined;
210
- keys?: boolean | undefined;
211
- values?: boolean | undefined;
212
- includes?: boolean | undefined;
213
- flatMap?: boolean | undefined;
214
- flat?: boolean | undefined;
215
- at?: boolean | undefined;
216
- findLast?: boolean | undefined;
217
- findLastIndex?: boolean | undefined;
218
- toReversed?: boolean | undefined;
219
- toSorted?: boolean | undefined;
220
- toSpliced?: boolean | undefined;
221
- with?: boolean | undefined;
222
- [Symbol.iterator]?: boolean | undefined;
223
- readonly [Symbol.unscopables]?: boolean | undefined;
224
- };
225
- readonly constructor: Function;
226
- dispatch: <E extends keyof Events<T_1>>(event: E, data?: Events<T>[E] | undefined) => void;
227
- dispose: () => void;
228
- on: <E extends keyof Events<T_1>>(event: E, listener: Listener<Events<T>[E]>) => void;
229
- once: <E extends keyof Events<T_1>>(event: E, listener: Listener<Events<T>[E]>) => void;
230
- };
53
+ declare const _default: <T>(input: T[], options?: Options) => API<T>;
231
54
  export default _default;
232
55
  export type { API as ReactiveArray };
@@ -1,27 +1,28 @@
1
1
  import { isInstanceOf, isNumber, isObject } from '@esportsplus/utilities';
2
2
  import { dispose, signal, Reactive } from '../signal.js';
3
3
  import object from './object.js';
4
- class ReactiveArray extends Array {
4
+ class ReactiveArray {
5
+ data;
5
6
  options;
6
7
  proxy;
7
8
  signal;
8
9
  constructor(data, proxy, options = {}) {
9
- super();
10
- for (let i = 0, n = data.length; i < n; i++) {
11
- super.push(data[i]);
12
- }
10
+ this.data = data;
13
11
  this.options = options;
14
12
  this.proxy = proxy;
15
13
  this.signal = signal(false);
16
14
  }
15
+ get length() {
16
+ return this.data.length;
17
+ }
17
18
  set length(n) {
18
- if (n > this.length) {
19
+ if (n > this.data.length) {
19
20
  return;
20
21
  }
21
22
  this.splice(n);
22
23
  }
23
24
  at(i) {
24
- let value = super.at(i);
25
+ let value = this.data[i];
25
26
  if (isInstanceOf(value, Reactive)) {
26
27
  return value.get();
27
28
  }
@@ -34,25 +35,26 @@ class ReactiveArray extends Array {
34
35
  this.signal.dispose();
35
36
  dispose(this);
36
37
  }
37
- indexOf(value) {
38
- for (let i = 0, n = this.length; i < n; i++) {
39
- if (this[i].value === value) {
38
+ indexOf(value, fromIndex) {
39
+ let data = this.data;
40
+ for (let i = fromIndex ?? 0, n = data.length; i < n; i++) {
41
+ if (data[i].value === value) {
40
42
  return i;
41
43
  }
42
44
  }
43
45
  return -1;
44
46
  }
45
47
  map(fn, i, n) {
46
- let proxy = this.proxy, values = [];
48
+ let { data, proxy } = this, values = [];
47
49
  if (i === undefined) {
48
50
  i = 0;
49
51
  }
50
52
  if (n === undefined) {
51
- n = this.length;
53
+ n = data.length;
52
54
  }
53
- n = Math.min(n, this.length);
55
+ n = Math.min(n, data.length);
54
56
  for (; i < n; i++) {
55
- let item = this[i];
57
+ let item = data[i];
56
58
  values.push(fn.call(proxy, isInstanceOf(item, Reactive) ? item.value : item, i));
57
59
  }
58
60
  return values;
@@ -64,7 +66,7 @@ class ReactiveArray extends Array {
64
66
  this.signal.once(event, listener);
65
67
  }
66
68
  pop() {
67
- let item = super.pop();
69
+ let item = this.data.pop();
68
70
  if (item !== undefined) {
69
71
  dispose(item);
70
72
  this.signal.dispatch('pop', { item });
@@ -72,17 +74,17 @@ class ReactiveArray extends Array {
72
74
  return item;
73
75
  }
74
76
  push(...input) {
75
- let items = factory(input, this.options), n = super.push(...items);
77
+ let items = factory(input, this.options), n = this.data.push(...items);
76
78
  this.signal.dispatch('push', { items });
77
79
  return n;
78
80
  }
79
81
  reverse() {
80
- super.reverse();
82
+ this.data.reverse();
81
83
  this.signal.dispatch('reverse');
82
84
  return this;
83
85
  }
84
86
  shift() {
85
- let item = super.shift();
87
+ let item = this.data.shift();
86
88
  if (item !== undefined) {
87
89
  dispose(item);
88
90
  this.signal.dispatch('shift', { item });
@@ -90,12 +92,12 @@ class ReactiveArray extends Array {
90
92
  return item;
91
93
  }
92
94
  sort(fn) {
93
- super.sort((a, b) => fn(isInstanceOf(a, Reactive) ? a.value : a, isInstanceOf(b, Reactive) ? b.value : b));
95
+ this.data.sort((a, b) => fn(isInstanceOf(a, Reactive) ? a.value : a, isInstanceOf(b, Reactive) ? b.value : b));
94
96
  this.signal.dispatch('sort');
95
97
  return this;
96
98
  }
97
- splice(start, deleteCount = super.length, ...input) {
98
- let items = factory(input, this.options), removed = super.splice(start, deleteCount, ...items);
99
+ splice(start, deleteCount = this.data.length, ...input) {
100
+ let items = factory(input, this.options), removed = this.data.splice(start, deleteCount, ...items);
99
101
  if (items.length > 0 || removed.length > 0) {
100
102
  dispose(removed);
101
103
  this.signal.dispatch('splice', {
@@ -107,7 +109,7 @@ class ReactiveArray extends Array {
107
109
  return removed;
108
110
  }
109
111
  unshift(...input) {
110
- let items = factory(input, this.options), length = super.unshift(...items);
112
+ let items = factory(input, this.options), length = this.data.unshift(...items);
111
113
  this.signal.dispatch('unshift', { items });
112
114
  return length;
113
115
  }
@@ -125,53 +127,26 @@ function factory(input, options = {}) {
125
127
  }
126
128
  return items;
127
129
  }
128
- function methods(a) {
129
- return {
130
- get constructor() {
131
- return a.constructor;
132
- },
133
- get length() {
134
- return a.length;
135
- },
136
- set length(n) {
137
- a.length = n;
138
- },
139
- at: (index) => a.at(index),
140
- dispatch: (event, data) => a.dispatch(event, data),
141
- dispose: () => a.dispose(),
142
- indexOf: (value) => a.indexOf(value),
143
- map: (fn, i, n) => a.map(fn, i, n),
144
- on: (event, listener) => a.on(event, listener),
145
- once: (event, listener) => a.once(event, listener),
146
- pop: () => a.pop(),
147
- push: (...input) => a.push(...input),
148
- reverse: () => a.reverse(),
149
- shift: () => a.shift(),
150
- sort: (fn) => a.sort(fn),
151
- splice: (start, deleteCount, ...input) => a.splice(start, deleteCount, ...input),
152
- unshift: (...input) => a.unshift(...input)
153
- };
154
- }
155
130
  export default (input, options = {}) => {
156
- let proxy = new Proxy({}, {
131
+ let wrapped = factory(input, options), proxy = new Proxy({}, {
157
132
  get(_, key) {
158
133
  if (isNumber(key)) {
159
- let value = a[key];
134
+ let value = wrapped[key];
160
135
  if (isInstanceOf(value, Reactive)) {
161
136
  return value.get();
162
137
  }
163
138
  return value;
164
139
  }
165
- else if (key in m) {
166
- return m[key];
140
+ else if (key in a) {
141
+ return a[key];
167
142
  }
168
- return a[key];
143
+ return wrapped[key];
169
144
  },
170
145
  set(_, key, value) {
171
146
  if (isNumber(key)) {
172
- let host = a[key];
147
+ let host = wrapped[key];
173
148
  if (host === undefined) {
174
- a[key] = factory([value], options)[0];
149
+ wrapped[key] = factory([value], options)[0];
175
150
  }
176
151
  else if (isInstanceOf(host, Reactive)) {
177
152
  host.set(value);
@@ -181,9 +156,12 @@ export default (input, options = {}) => {
181
156
  }
182
157
  return true;
183
158
  }
184
- return a[key] = value;
159
+ else if (key === 'length') {
160
+ return a.length = value;
161
+ }
162
+ return false;
185
163
  }
186
164
  });
187
- let a = new ReactiveArray(factory(input, options), proxy), m = methods(a);
165
+ let a = new ReactiveArray(wrapped, proxy);
188
166
  return proxy;
189
167
  };
package/package.json CHANGED
@@ -12,7 +12,7 @@
12
12
  "private": false,
13
13
  "type": "module",
14
14
  "types": "build/index.d.ts",
15
- "version": "0.4.1",
15
+ "version": "0.4.2",
16
16
  "scripts": {
17
17
  "build": "tsc && tsc-alias",
18
18
  "-": "-"
@@ -1,11 +1,11 @@
1
- import { Infer, Prettify } from '~/types';
1
+ import { Infer } from '~/types';
2
2
  import { isInstanceOf, isNumber, isObject } from '@esportsplus/utilities';
3
3
  import { dispose, signal, Reactive } from '~/signal';
4
4
  import { Listener, Options, ReactiveObject, Signal } from '~/types';
5
5
  import object from './object';
6
6
 
7
7
 
8
- type API<T> = Prettify< Infer<T>[] & ReturnType<typeof methods<T>> >;
8
+ type API<T> = Infer<T>[] & ReactiveArray<T>;
9
9
 
10
10
  type Events<T> = {
11
11
  pop: {
@@ -36,31 +36,27 @@ type Events<T> = {
36
36
  type Item<T> = T extends Record<PropertyKey, unknown> ? ReactiveObject<T> : Signal<T>;
37
37
 
38
38
 
39
- // REMINDER:
40
- // - @ts-ignore flags are supressing type mismatch error
41
- // - Input values are being transformed by this class into reactive values and back during get
42
- class ReactiveArray<T> extends Array<Item<T>> {
39
+ class ReactiveArray<T> {
40
+ private data: Item<T>[]
43
41
  private options: Options;
44
42
  private proxy: API<T>;
45
43
  private signal: Signal<boolean>;
46
44
 
47
45
 
48
46
  constructor(data: Item<T>[], proxy: API<T>, options: Options = {}) {
49
- super();
50
-
51
- // Only method I could use to prevent TS and runtime JS errors
52
- for (let i = 0, n = data.length; i < n; i++) {
53
- super.push(data[i]);
54
- }
55
-
47
+ this.data = data;
56
48
  this.options = options;
57
49
  this.proxy = proxy;
58
50
  this.signal = signal(false);
59
51
  }
60
52
 
61
53
 
54
+ get length(): number {
55
+ return this.data.length;
56
+ }
57
+
62
58
  set length(n: number) {
63
- if (n > this.length) {
59
+ if (n > this.data.length) {
64
60
  return;
65
61
  }
66
62
 
@@ -69,7 +65,7 @@ class ReactiveArray<T> extends Array<Item<T>> {
69
65
 
70
66
 
71
67
  at(i: number) {
72
- let value = super.at(i);
68
+ let value = this.data[i];
73
69
 
74
70
  if (isInstanceOf(value, Reactive)) {
75
71
  return value.get();
@@ -78,7 +74,7 @@ class ReactiveArray<T> extends Array<Item<T>> {
78
74
  return value;
79
75
  }
80
76
 
81
- dispatch<E extends keyof Events<T>>(event: E, data?: Events<T>[E]) {
77
+ dispatch<E extends keyof Events<unknown>>(event: E, data?: Events<T>[E]) {
82
78
  this.signal.dispatch(event, data);
83
79
  }
84
80
 
@@ -87,10 +83,11 @@ class ReactiveArray<T> extends Array<Item<T>> {
87
83
  dispose(this);
88
84
  }
89
85
 
90
- // @ts-ignore
91
- indexOf(value: T) {
92
- for (let i = 0, n = this.length; i < n; i++) {
93
- if (this[i].value === value) {
86
+ indexOf(value: T, fromIndex?: number) {
87
+ let data = this.data;
88
+
89
+ for (let i = fromIndex ?? 0, n = data.length; i < n; i++) {
90
+ if (data[i].value === value) {
94
91
  return i;
95
92
  }
96
93
  }
@@ -98,9 +95,8 @@ class ReactiveArray<T> extends Array<Item<T>> {
98
95
  return -1;
99
96
  }
100
97
 
101
- // @ts-ignore
102
98
  map<U>(fn: (this: API<T>, value: T, i: number) => U, i?: number, n?: number) {
103
- let proxy = this.proxy,
99
+ let { data, proxy } = this,
104
100
  values: U[] = [];
105
101
 
106
102
  if (i === undefined) {
@@ -108,13 +104,13 @@ class ReactiveArray<T> extends Array<Item<T>> {
108
104
  }
109
105
 
110
106
  if (n === undefined) {
111
- n = this.length;
107
+ n = data.length;
112
108
  }
113
109
 
114
- n = Math.min(n, this.length);
110
+ n = Math.min(n, data.length);
115
111
 
116
112
  for (; i < n; i++) {
117
- let item = this[i];
113
+ let item = data[i];
118
114
 
119
115
  values.push(
120
116
  fn.call(proxy, isInstanceOf(item, Reactive) ? item.value : item, i)
@@ -124,16 +120,16 @@ class ReactiveArray<T> extends Array<Item<T>> {
124
120
  return values;
125
121
  }
126
122
 
127
- on<E extends keyof Events<T>>(event: E, listener: Listener<Events<T>[E]>) {
123
+ on<E extends keyof Events<unknown>>(event: E, listener: Listener<Events<T>[E]>) {
128
124
  this.signal.on(event, listener);
129
125
  }
130
126
 
131
- once<E extends keyof Events<T>>(event: E, listener: Listener<Events<T>[E]>) {
127
+ once<E extends keyof Events<unknown>>(event: E, listener: Listener<Events<T>[E]>) {
132
128
  this.signal.once(event, listener);
133
129
  }
134
130
 
135
131
  pop() {
136
- let item = super.pop();
132
+ let item = this.data.pop();
137
133
 
138
134
  if (item !== undefined) {
139
135
  dispose(item);
@@ -143,26 +139,24 @@ class ReactiveArray<T> extends Array<Item<T>> {
143
139
  return item;
144
140
  }
145
141
 
146
- // @ts-ignore
147
142
  push(...input: T[]) {
148
143
  let items = factory(input, this.options),
149
- n = super.push(...items);
144
+ n = this.data.push(...items);
150
145
 
151
146
  this.signal.dispatch('push', { items });
152
147
 
153
148
  return n;
154
149
  }
155
150
 
156
- // @ts-ignore
157
151
  reverse() {
158
- super.reverse();
152
+ this.data.reverse();
159
153
  this.signal.dispatch('reverse');
160
154
 
161
155
  return this;
162
156
  }
163
157
 
164
158
  shift() {
165
- let item = super.shift();
159
+ let item = this.data.shift();
166
160
 
167
161
  if (item !== undefined) {
168
162
  dispose(item);
@@ -172,9 +166,8 @@ class ReactiveArray<T> extends Array<Item<T>> {
172
166
  return item;
173
167
  }
174
168
 
175
- // @ts-ignore
176
169
  sort(fn: (a: T, b: T) => number) {
177
- super.sort((a, b) => fn(
170
+ this.data.sort((a, b) => fn(
178
171
  isInstanceOf(a, Reactive) ? a.value : a,
179
172
  isInstanceOf(b, Reactive) ? b.value : b
180
173
  ));
@@ -183,10 +176,9 @@ class ReactiveArray<T> extends Array<Item<T>> {
183
176
  return this;
184
177
  }
185
178
 
186
- // @ts-ignore
187
- splice(start: number, deleteCount: number = super.length, ...input: T[]) {
179
+ splice(start: number, deleteCount: number = this.data.length, ...input: T[]) {
188
180
  let items = factory(input, this.options),
189
- removed = super.splice(start, deleteCount, ...items);
181
+ removed = this.data.splice(start, deleteCount, ...items);
190
182
 
191
183
  if (items.length > 0 || removed.length > 0) {
192
184
  dispose(removed);
@@ -200,10 +192,9 @@ class ReactiveArray<T> extends Array<Item<T>> {
200
192
  return removed;
201
193
  }
202
194
 
203
- // @ts-ignore
204
195
  unshift(...input: T[]) {
205
196
  let items = factory(input, this.options),
206
- length = super.unshift(...items);
197
+ length = this.data.unshift(...items);
207
198
 
208
199
  this.signal.dispatch('unshift', { items });
209
200
 
@@ -231,60 +222,13 @@ function factory<T>(input: T[], options: Options = {}) {
231
222
  return items;
232
223
  }
233
224
 
234
- function methods<T>(a: ReactiveArray<T>): Prettify<
235
- {
236
- get constructor(): typeof a['constructor'];
237
- get length(): number;
238
- set length(n: number);
239
- } & Pick<
240
- typeof a,
241
- 'at' |
242
- 'dispatch' | 'dispose' |
243
- 'indexOf' |
244
- 'map' |
245
- 'on' | 'once' |
246
- 'pop' | 'push' |
247
- 'reverse' |
248
- 'shift' | 'sort' | 'splice' |
249
- 'unshift'
250
- >
251
- > {
252
- return {
253
- get constructor() {
254
- return a.constructor;
255
- },
256
- get length() {
257
- return a.length;
258
- },
259
- set length(n: number) {
260
- a.length = n;
261
- },
262
- at: (index) => a.at(index),
263
- dispatch: (event, data) => a.dispatch(event, data),
264
- dispose: () => a.dispose(),
265
- indexOf: (value) => a.indexOf(value),
266
- map: (fn, i, n) => a.map(fn, i, n),
267
- on: (event, listener) => a.on(event, listener),
268
- once: (event, listener) => a.once(event, listener),
269
- pop: () => a.pop(),
270
- push: (...input) => a.push(...input),
271
- reverse: () => a.reverse(),
272
- shift: () => a.shift(),
273
- sort: (fn) => a.sort(fn),
274
- splice: (start, deleteCount, ...input) => a.splice(start, deleteCount, ...input),
275
- unshift: (...input) => a.unshift(...input)
276
- };
277
- }
278
225
 
279
-
280
- // - Proxies are slow...
281
- // - `this.[property]` goes through proxy
282
- // - Wrapper slows down creation in exchange for 'faster' runtime use
283
226
  export default <T>(input: T[], options: Options = {}) => {
284
- let proxy = new Proxy({}, {
227
+ let wrapped = factory(input, options),
228
+ proxy = new Proxy({}, {
285
229
  get(_: any, key: any) {
286
230
  if (isNumber(key)) {
287
- let value = a[key];
231
+ let value = wrapped[key];
288
232
 
289
233
  if (isInstanceOf(value, Reactive)) {
290
234
  return value.get();
@@ -292,18 +236,18 @@ export default <T>(input: T[], options: Options = {}) => {
292
236
 
293
237
  return value;
294
238
  }
295
- else if (key in m) {
296
- return m[key as keyof typeof m];
239
+ else if (key in a) {
240
+ return a[key as keyof typeof a];
297
241
  }
298
242
 
299
- return a[key];
243
+ return wrapped[key];
300
244
  },
301
245
  set(_: any, key: any, value: any) {
302
246
  if (isNumber(key)) {
303
- let host = a[key];
247
+ let host = wrapped[key];
304
248
 
305
249
  if (host === undefined) {
306
- a[key] = factory([value] as T[], options)[0];
250
+ wrapped[key] = factory([value] as T[], options)[0];
307
251
  }
308
252
  else if (isInstanceOf(host, Reactive)) {
309
253
  host.set(value);
@@ -314,13 +258,15 @@ export default <T>(input: T[], options: Options = {}) => {
314
258
 
315
259
  return true;
316
260
  }
261
+ else if (key === 'length') {
262
+ return a.length = value;
263
+ }
317
264
 
318
- return a[key] = value;
265
+ return false;
319
266
  }
320
267
  }) as API<T>;
321
268
 
322
- let a = new ReactiveArray(factory(input, options), proxy),
323
- m = methods(a);
269
+ let a = new ReactiveArray(wrapped, proxy);
324
270
 
325
271
  return proxy;
326
272
  };