apical-store
Advanced tools
Comparing version 0.0.80 to 0.0.81
@@ -98,2 +98,14 @@ (function (global, factory) { | ||
} | ||
function isSpecialObj(input) { | ||
if (input instanceof RegExp || | ||
input instanceof Map || | ||
input instanceof Set || | ||
input instanceof WeakMap || | ||
input instanceof WeakSet || | ||
input instanceof Promise || | ||
input instanceof Date || | ||
input instanceof Error) | ||
return true; | ||
return false; | ||
} | ||
@@ -127,7 +139,13 @@ /** | ||
object(source, oMeta, visited) { | ||
const target = {}; | ||
let target = {}; | ||
if (isSpecialObj(source)) { | ||
target = source; | ||
} | ||
else { | ||
// for regular objects copy and go deeper | ||
for (const key in source) { | ||
target[key] = prepare.getObservedOf(source[key], key, oMeta, visited); | ||
} | ||
} | ||
target[oMetaKey] = oMeta; | ||
for (const key in source) { | ||
target[key] = prepare.getObservedOf(source[key], key, oMeta, visited); | ||
} | ||
// also copy methods, getters and setters | ||
@@ -564,2 +582,9 @@ copyPropertiesTo(source, target); | ||
} | ||
get(target, key, receiver) { | ||
if (isSpecialObj(target)) { | ||
const value = Reflect.get(target, key, receiver); | ||
return typeof value === "function" ? value.bind(target) : value; | ||
} | ||
return target[key]; | ||
} | ||
} | ||
@@ -566,0 +591,0 @@ class ObservableArrayMeta extends ObservableMeta { |
@@ -34,2 +34,3 @@ import { proxiedArrayMethods } from "./arr"; | ||
constructor(properties: MetaProperties<T>); | ||
get(target: T, key: string | symbol, receiver: any): any; | ||
} | ||
@@ -36,0 +37,0 @@ export declare class ObservableArrayMeta<G, T extends Array<G>> extends ObservableMeta<any> { |
@@ -133,2 +133,9 @@ import { proxiedArrayMethods } from "./arr"; | ||
} | ||
get(target, key, receiver) { | ||
if (utils.isSpecialObj(target)) { | ||
const value = Reflect.get(target, key, receiver); | ||
return typeof value === "function" ? value.bind(target) : value; | ||
} | ||
return target[key]; | ||
} | ||
} | ||
@@ -135,0 +142,0 @@ export class ObservableArrayMeta extends ObservableMeta { |
import { oMetaKey } from "./const"; | ||
import { ObservableArrayMeta, ObservableObjectMeta } from "./meta"; | ||
import { ObservableArrayMeta, ObservableObjectMeta, } from "./meta"; | ||
import * as utils from "./utils"; | ||
export const prepare = { | ||
object(source, oMeta, visited) { | ||
const target = {}; | ||
let target = {}; | ||
if (utils.isSpecialObj(source)) { | ||
target = source; | ||
} | ||
else { | ||
// for regular objects copy and go deeper | ||
for (const key in source) { | ||
target[key] = prepare.getObservedOf(source[key], key, oMeta, visited); | ||
} | ||
} | ||
target[oMetaKey] = oMeta; | ||
for (const key in source) { | ||
target[key] = prepare.getObservedOf(source[key], key, oMeta, visited); | ||
} | ||
// also copy methods, getters and setters | ||
@@ -12,0 +18,0 @@ utils.copyPropertiesTo(source, target); |
@@ -6,1 +6,2 @@ import { ObservableMeta } from "./meta"; | ||
export declare function isTrueObj(obj: any): boolean; | ||
export declare function isSpecialObj(input: any): boolean; |
@@ -75,1 +75,13 @@ // polyfill | ||
} | ||
export function isSpecialObj(input) { | ||
if (input instanceof RegExp || | ||
input instanceof Map || | ||
input instanceof Set || | ||
input instanceof WeakMap || | ||
input instanceof WeakSet || | ||
input instanceof Promise || | ||
input instanceof Date || | ||
input instanceof Error) | ||
return true; | ||
return false; | ||
} |
{ | ||
"name": "apical-store", | ||
"version": "0.0.80", | ||
"version": "0.0.81", | ||
"description": "reactive-syncable-datastore", | ||
@@ -11,3 +11,4 @@ "main": "dist/bundle.js", | ||
"test": "vitest", | ||
"build": "rollup -c && tsc" | ||
"build": "rollup -c && tsc", | ||
"prepublish": "npm run build" | ||
}, | ||
@@ -14,0 +15,0 @@ "author": "alselawi", |
import { proxiedArrayMethods } from "./arr"; | ||
import { Change } from "./change"; | ||
import { oMetaKey, DELETE, INSERT, UPDATE } from "./const"; | ||
import { oMetaKey, DELETE, INSERT, UPDATE } from "./const"; | ||
import { prepare } from "./prepare"; | ||
@@ -196,5 +196,16 @@ import { observed, Observer, PrepareFunction } from "./types"; | ||
} | ||
get(target: T, key: string | symbol, receiver: any) { | ||
if (utils.isSpecialObj(target)) { | ||
const value = Reflect.get(target, key, receiver); | ||
return typeof value === "function" ? value.bind(target) : value; | ||
} | ||
return (target as any)[key]; | ||
} | ||
} | ||
export class ObservableArrayMeta<G, T extends Array<G>> extends ObservableMeta<any> { | ||
export class ObservableArrayMeta< | ||
G, | ||
T extends Array<G> | ||
> extends ObservableMeta<any> { | ||
constructor(properties: MetaProperties<T>) { | ||
@@ -207,2 +218,2 @@ super(properties, prepare.array); | ||
} | ||
} | ||
} |
import { oMetaKey } from "./const"; | ||
import { ObservableArrayMeta, ObservableMeta, ObservableObjectMeta } from "./meta"; | ||
import { | ||
ObservableArrayMeta, | ||
ObservableMeta, | ||
ObservableObjectMeta, | ||
} from "./meta"; | ||
import { observed } from "./types"; | ||
@@ -12,7 +16,12 @@ import * as utils from "./utils"; | ||
): observed<T> { | ||
const target: observed<T> = {} as any; | ||
let target: observed<T> = {} as any; | ||
if (utils.isSpecialObj(source)) { | ||
target = source as any; | ||
} else { | ||
// for regular objects copy and go deeper | ||
for (const key in source) { | ||
target[key] = prepare.getObservedOf(source[key], key, oMeta, visited); | ||
} | ||
} | ||
target[oMetaKey] = oMeta; | ||
for (const key in source) { | ||
target[key] = prepare.getObservedOf(source[key], key, oMeta, visited); | ||
} | ||
// also copy methods, getters and setters | ||
@@ -19,0 +28,0 @@ utils.copyPropertiesTo(source, target); |
@@ -87,1 +87,16 @@ import { ObservableMeta } from "./meta"; | ||
} | ||
export function isSpecialObj(input: any) { | ||
if ( | ||
input instanceof RegExp || | ||
input instanceof Map || | ||
input instanceof Set || | ||
input instanceof WeakMap || | ||
input instanceof WeakSet || | ||
input instanceof Promise || | ||
input instanceof Date || | ||
input instanceof Error | ||
) | ||
return true; | ||
return false; | ||
} |
@@ -448,3 +448,85 @@ import { describe, test, it, expect, vi } from "vitest"; | ||
}); | ||
it("deeply nested classes methods should also be copied", async () => { | ||
class Child { | ||
name: string = ""; | ||
age: number = 0; | ||
get ageInMonths () { | ||
return this.age * 12; | ||
} | ||
update(arg: number) { | ||
this.age = arg; | ||
} | ||
} | ||
class Parent { | ||
name: string = ""; | ||
children: Child[] = []; | ||
} | ||
const parent = new Parent(); | ||
const observableParent = new Observable(parent); | ||
observableParent.target.children.push(new Child()); | ||
observableParent.target.children.push(new Child()); | ||
await new Promise((r) => setTimeout(r, 100)); | ||
let changes: Change<any>[] = []; | ||
observableParent.observe((c) => { | ||
changes = c; | ||
}); | ||
observableParent.target.children[0].update(12); | ||
observableParent.target.children[1].update(14); | ||
await new Promise((r) => setTimeout(r, 100)); | ||
expect(observableParent.target.children[0].ageInMonths).toBe(12 * 12); | ||
expect(observableParent.target.children[1].ageInMonths).toBe(14 * 12); | ||
expect(changes.length).toBe(2); | ||
expect(changes[0].type).toBe("update"); | ||
expect(changes[0].path).toEqual(["children", 0, "age"]); | ||
expect(changes[0].value).toBe(12); | ||
expect(changes[1].type).toBe("update"); | ||
expect(changes[1].path).toEqual(["children", 1, "age"]); | ||
expect(changes[1].value).toBe(14); | ||
}); | ||
it("Native JS objects should also be copied", async () => { | ||
let obj = { | ||
date: new Date(), | ||
regex: /abcd/, | ||
array: [1, 2, 3], | ||
map: new Map([["a", 1], ["b", 2]]), | ||
set: new Set([1, 2, 3]), | ||
arrayBuffer: new ArrayBuffer(8), | ||
typedArray: new Uint8Array(new ArrayBuffer(8)), | ||
dataView: new DataView(new ArrayBuffer(8)), | ||
promise: Promise.resolve(1), | ||
proxy: new Proxy({}, {}), | ||
weakMap: new WeakMap([[{}, 1]]), | ||
weakSet: new WeakSet([{}]), | ||
symbol: Symbol("abc"), | ||
bigint: 123n, | ||
error: new Error("error"), | ||
} | ||
const observableObject = new Observable(obj); | ||
expect(observableObject.target.date.getMonth()).toEqual(obj.date.getMonth()); | ||
expect(observableObject.target.regex.test("abcd")).toEqual(obj.regex.test("abcd")); | ||
expect(observableObject.target.array.pop()).toEqual(obj.array.pop()); | ||
expect(observableObject.target.map.get("a")).toEqual(obj.map.get("a")); | ||
expect(observableObject.target.set.has(1)).toEqual(obj.set.has(1)); | ||
expect((await observableObject.target.promise).toPrecision()).toEqual((await obj.promise).toPrecision()); | ||
expect(observableObject.target.weakMap.get({})).toEqual(obj.weakMap.get({})); | ||
expect(observableObject.target.weakSet.has({})).toEqual(obj.weakSet.has({})); | ||
expect(observableObject.target.symbol).toEqual(obj.symbol); | ||
expect(observableObject.target.bigint).toEqual(obj.bigint); | ||
expect(observableObject.target.error.message).toEqual(obj.error.message); | ||
}); | ||
}); | ||
}); | ||
}); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
260316
7050