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

Commit 9638b84

Browse files
committed
[ADD] Memory: memory will be use for history, target the node to redraw...
1 parent 6597826 commit 9638b84

File tree

8 files changed

+5178
-0
lines changed

8 files changed

+5178
-0
lines changed

packages/core/src/Memory/Memory.ts

Lines changed: 902 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
import {
2+
MemoryAllowedType,
3+
MemoryAllowedObjectType,
4+
MemoryWorker,
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+
NotVersionableError,
15+
VersionableAllreadyVersionableError,
16+
memoryProxyPramsKey,
17+
} from './const';
18+
19+
export class VersionableID extends Number {}
20+
VersionableID.prototype[memoryProxyNotVersionableKey] = true;
21+
22+
let MemoryID = 0;
23+
export function generateVersionableID(): VersionableID {
24+
return new VersionableID(++MemoryID);
25+
}
26+
27+
// Magic memory key that is set on the object through a symbol (inaccessible for
28+
// others). It stores everything that is useful for the memory to handle this object.
29+
export interface VersionableParams {
30+
ID: VersionableID; // proxy id in memory.
31+
memory?: MemoryWorker; // interface for versionale to access memory (since we don't want to give them the true memory object !)
32+
proxy: MemoryAllowedObjectType; // proxy itself (what we return, what people actually manipulate)
33+
object: MemoryAllowedObjectType; // Object that is proxified (it is synchronized with the proxy because the proxy updates it at some points ... -- not the Set !)
34+
linkCallback: (memory: MemoryWorker) => void; // function to call when this versionable is linked to a memory
35+
synchronize: () => void; // Synchronize the versionable object with the memory information.
36+
verify: (obj: MemoryAllowedType) => boolean; // Verify if the given proxy matches the versionable object.
37+
MemoryType: typeof MemoryTypeObject | typeof MemoryTypeArray | typeof MemoryTypeSet;
38+
isDiffRoot?: true; // is it a standalone object or does it only makes sense as part of an other object's structure ?
39+
}
40+
41+
// queue of stuff to proxify
42+
const toProxify = new Map<MemoryAllowedType, Array<(proxy: MemoryAllowedType) => void>>();
43+
44+
/**
45+
* Take an object and return a versionable proxy to this object.
46+
*
47+
* @param object
48+
*/
49+
export function makeVersionable<T extends MemoryAllowedType>(object: T): T {
50+
const params = object[memoryProxyPramsKey] as VersionableParams;
51+
if (params) {
52+
if (params.object === object) {
53+
throw new VersionableAllreadyVersionableError();
54+
}
55+
if (params && params.verify(object)) {
56+
return object;
57+
}
58+
}
59+
const proxy = _proxify(object);
60+
toProxify.forEach((callbacks, torototo) => {
61+
toProxify.delete(torototo);
62+
const proxy = _proxify(torototo);
63+
callbacks.forEach(callback => callback(proxy));
64+
});
65+
return proxy;
66+
}
67+
/**
68+
* Create a proxy from a versionable with given handler.
69+
*
70+
* @param versionable
71+
* @param handler
72+
*/
73+
export function proxifyVersionable<T extends MemoryAllowedType>(
74+
versionable: T,
75+
handler: ProxyHandler<object>,
76+
): T {
77+
const newProxy = new Proxy(versionable as object, handler);
78+
versionable[memoryProxyPramsKey].proxy = newProxy;
79+
return newProxy as T;
80+
}
81+
/**
82+
* Mark the current object as not versionable in memory.
83+
* A non versionable object is not linked to the memory. The memory does not
84+
* take care of the change inside this object, and this object is nerver
85+
* immutable.
86+
*
87+
* @param object
88+
*/
89+
export function markNotVersionable(object: MemoryAllowedType): void {
90+
object[memoryProxyNotVersionableKey] = true;
91+
}
92+
/**
93+
* Throw an error if the given object is not a versionable.
94+
*
95+
* @param object
96+
*/
97+
export function _checkVersionable<T extends MemoryAllowedType>(object: T): void {
98+
if (
99+
typeof object !== 'object' ||
100+
object === null ||
101+
object[memoryProxyNotVersionableKey] // this is set by the user
102+
) {
103+
return;
104+
}
105+
106+
const params = object[memoryProxyPramsKey];
107+
if (params) {
108+
if (params.object === object) {
109+
throw new VersionableAllreadyVersionableError();
110+
}
111+
if (params.verify(object)) {
112+
// Already versioned ! (we could have inherited from the `params` of
113+
// another, already versioned object, but we might not)
114+
return;
115+
}
116+
}
117+
118+
throw new NotVersionableError();
119+
}
120+
// Recursive proxification is very limited because of callback depth. To
121+
// circumvent this issue, we queue the proxification of children.
122+
export function _stackedProxify<T extends MemoryAllowedType>(
123+
customClass: T,
124+
callback: (proxy: T) => void,
125+
): void {
126+
if (
127+
!customClass ||
128+
typeof customClass !== 'object' ||
129+
customClass[memoryProxyNotVersionableKey]
130+
) {
131+
callback(customClass);
132+
return;
133+
}
134+
const params = customClass[memoryProxyPramsKey];
135+
if (params) {
136+
callback(params.proxy);
137+
}
138+
const callbacks = toProxify.get(customClass) || [];
139+
toProxify.set(customClass, callbacks);
140+
callbacks.push(callback);
141+
}
142+
143+
function _proxify<T extends MemoryAllowedType>(customClass: T): T {
144+
const params = customClass[memoryProxyPramsKey];
145+
if (params && params.verify(customClass)) {
146+
return params.proxy;
147+
}
148+
let proxy: T;
149+
if (customClass instanceof Set) {
150+
proxy = _proxifySet(customClass) as T;
151+
} else if (customClass instanceof Array) {
152+
proxy = _proxifyArray(customClass) as T;
153+
} else {
154+
proxy = _proxifyObject(customClass as Record<string, MemoryAllowedType>) as T;
155+
}
156+
return proxy;
157+
}

0 commit comments

Comments
 (0)