Skip to content
This repository was archived by the owner on May 5, 2021. It is now read-only.

Commit 3ab4dd2

Browse files
committed
wip memory
1 parent 5f76418 commit 3ab4dd2

8 files changed

+4847
-0
lines changed

packages/core/src/Memory/Memory.ts

+623
Large diffs are not rendered by default.
+133
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
import {
2+
AllowedMemory,
3+
AllowedObject,
4+
MemoryVersionable,
5+
MemoryTypeArray,
6+
MemoryTypeObject,
7+
MemoryTypeSet,
8+
} from './Memory';
9+
import { proxifyObject } from './VersionableObject';
10+
import { proxifyArray } from './VersionableArray';
11+
import { proxifySet } from './VersionableSet';
12+
import {
13+
memoryProxyNotVersionableKey,
14+
NotVersionableErrorMessage,
15+
VersionableAllreadyVersionableErrorMessage,
16+
memoryProxyPramsKey,
17+
} from './const';
18+
19+
export class ProxyUniqID extends Number {}
20+
ProxyUniqID.prototype[memoryProxyNotVersionableKey] = true;
21+
22+
let MemoryID = 0;
23+
export function generateMemoryID(): ProxyUniqID {
24+
// Unique ID (not really related to memory)
25+
return new ProxyUniqID(++MemoryID);
26+
}
27+
28+
// const key = new ProxyUniqID(1);
29+
// const rec = {};
30+
// rec[key as number] = 4;
31+
32+
// Magic memory key that is set on the object through a symbol (inaccessible for
33+
// others). It stores everything that is useful for the memory to handle this object.
34+
export interface VersionableParams {
35+
ID: ProxyUniqID; // id du couple (proxy, object) en mémoire (number extension)
36+
memory?: MemoryVersionable; // interface for versionale to access memory (since we don't want to give them the true memory object !)
37+
proxy: AllowedObject; // proxy itself (what we return, what people actually manipulate)
38+
object: AllowedObject; // Object that is proxified (it is synchronized with the proxy because the proxy updates it at some points ... -- not the Set !)
39+
linkCallback: (memory: MemoryVersionable) => void; // function to call when this versionable is linked to a memory
40+
sync: () => void;
41+
itsme: (obj: AllowedMemory) => boolean;
42+
MemoryType: typeof MemoryTypeObject | typeof MemoryTypeArray | typeof MemoryTypeSet;
43+
willBeRootDiff?: true; // is it a standalone object or does it only makes sense as part of an other object's structure ?
44+
}
45+
46+
// queue of stuff to proxify
47+
const objectStackToProxify = new Map<AllowedMemory, Array<(proxy: AllowedMemory) => void>>();
48+
49+
export function makeVersionable<T extends AllowedMemory>(customClass: T): T {
50+
const params = customClass[memoryProxyPramsKey] as VersionableParams;
51+
if (params && params.itsme(customClass)) {
52+
VersionableAllreadyVersionableErrorMessage();
53+
}
54+
const proxy = _proxify(customClass);
55+
objectStackToProxify.forEach((callbacks, torototo) => {
56+
objectStackToProxify.delete(torototo);
57+
const proxy = _proxify(torototo);
58+
callbacks.forEach(callback => callback(proxy));
59+
});
60+
return proxy;
61+
}
62+
export function createProxyWithVersionable<T extends AllowedMemory>(
63+
proxy: T,
64+
handler: ProxyHandler<object>,
65+
): T {
66+
const newProxy = new Proxy(proxy as object, handler);
67+
proxy[memoryProxyPramsKey].proxy = newProxy;
68+
return newProxy as T;
69+
}
70+
export function markNotVersionable(customClass: AllowedMemory): void {
71+
customClass[memoryProxyNotVersionableKey] = true;
72+
}
73+
// the argument can be anything actually, not necessarily a class
74+
export function checkIfProxy<T extends AllowedMemory>(customClass: T): T {
75+
if (
76+
typeof customClass !== 'object' ||
77+
customClass === null ||
78+
customClass[memoryProxyNotVersionableKey] // this is set by the user
79+
) {
80+
return customClass;
81+
}
82+
83+
const params = customClass[memoryProxyPramsKey];
84+
if (params) {
85+
if (params.object === customClass) {
86+
VersionableAllreadyVersionableErrorMessage();
87+
}
88+
if (params.itsme(customClass)) {
89+
// Already versioned ! (we could have inherited from the `params` of
90+
// another, already versioned object, but we might not)
91+
return customClass;
92+
}
93+
}
94+
95+
NotVersionableErrorMessage();
96+
}
97+
function _proxify<T extends AllowedMemory>(customClass: T): T {
98+
const params = customClass[memoryProxyPramsKey];
99+
if (params && params.itsme(customClass)) {
100+
return params.proxy;
101+
}
102+
let proxy: T;
103+
if (customClass instanceof Set) {
104+
proxy = proxifySet(customClass) as T;
105+
} else if (customClass instanceof Array) {
106+
proxy = proxifyArray(customClass) as T;
107+
} else {
108+
proxy = proxifyObject(customClass as Record<string, AllowedMemory>) as T;
109+
}
110+
return proxy;
111+
}
112+
// Recursive proxification is very limited because of callback depth. To
113+
// circumvent this issue, we queue the proxification of children.
114+
export function stackedProxify<T extends AllowedMemory>(
115+
customClass: T,
116+
callback: (proxy: T) => void,
117+
): void {
118+
if (
119+
!customClass ||
120+
typeof customClass !== 'object' ||
121+
customClass[memoryProxyNotVersionableKey]
122+
) {
123+
callback(customClass);
124+
return;
125+
}
126+
const params = customClass[memoryProxyPramsKey];
127+
if (params) {
128+
callback(params.proxy);
129+
}
130+
const callbacks = objectStackToProxify.get(customClass) || [];
131+
objectStackToProxify.set(customClass, callbacks);
132+
callbacks.push(callback);
133+
}

0 commit comments

Comments
 (0)