@pistonite/pure 0.0.20 → 0.21.0
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.
- package/package.json +1 -1
- package/src/memory/index.ts +8 -0
- package/src/memory/weak.ts +139 -0
- package/src/pref/dark.ts +1 -1
- package/src/pref/locale.ts +1 -1
- package/src/sync/index.ts +0 -2
- /package/src/{sync → memory}/cell.ts +0 -0
- /package/src/{sync → memory}/persist.ts +0 -0
package/package.json
CHANGED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
export type ExternalWeakRef<TUnderlying, TType> = {
|
|
2
|
+
/**
|
|
3
|
+
* A marker value for the underlying object type.
|
|
4
|
+
*
|
|
5
|
+
* This is commonly a string literal or a symbol.
|
|
6
|
+
*/
|
|
7
|
+
type: TType;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The underlying object reference.
|
|
11
|
+
*/
|
|
12
|
+
ref: TUnderlying | undefined;
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Free the underlying object.
|
|
16
|
+
*/
|
|
17
|
+
free: () => void;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Update the underlying object reference.
|
|
21
|
+
*
|
|
22
|
+
* If the new reference is the same as the old one, nothing will happen.
|
|
23
|
+
* If the old reference is not undefined, it will be freed.
|
|
24
|
+
*/
|
|
25
|
+
set: (value: TUnderlying | undefined) => void;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export type ExternalWeakRefConstructor<TUnderlying, TType> = {
|
|
29
|
+
/**
|
|
30
|
+
* A marker value for the underlying object type.
|
|
31
|
+
*
|
|
32
|
+
* This is commonly a string literal or a symbol.
|
|
33
|
+
*/
|
|
34
|
+
marker: TType;
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* The function to free the underlying object.
|
|
38
|
+
*/
|
|
39
|
+
free: (obj: TUnderlying) => void;
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Create a weak reference type for managing externally memory-managed object. This means
|
|
44
|
+
* the objects needs to be freed manually by the external code.
|
|
45
|
+
*
|
|
46
|
+
* The `marker` option is used to distinguish between different types of weak references
|
|
47
|
+
* with the same underlying representation for the reference.
|
|
48
|
+
*
|
|
49
|
+
* Note that the underlying representation should not be undefined-able!
|
|
50
|
+
*
|
|
51
|
+
* ## Example
|
|
52
|
+
* ```typescript
|
|
53
|
+
* import { makeExternalWeakRefType } from "@pistonite/pure/memory";
|
|
54
|
+
*
|
|
55
|
+
* // assume `number` is the JS type used to represent the external object
|
|
56
|
+
* // for example, this can be a pointer to a C++ object
|
|
57
|
+
* declare function freeFoo(obj: number) => void;
|
|
58
|
+
*
|
|
59
|
+
* // some function that allocates a foo object externally and returns
|
|
60
|
+
* // a reference
|
|
61
|
+
* declare function getFoo(): number;
|
|
62
|
+
*
|
|
63
|
+
* const makeFooRef = makeExternalWeakRefType({
|
|
64
|
+
* marker: "foo",
|
|
65
|
+
* free: (obj) => {
|
|
66
|
+
* freeFoo(obj);
|
|
67
|
+
* }
|
|
68
|
+
* });
|
|
69
|
+
* type FooRef = ReturnType<typeof makeFooRef>;
|
|
70
|
+
*
|
|
71
|
+
* // create a reference to a foo object
|
|
72
|
+
* // now this reference can be passed around in JS,
|
|
73
|
+
* // as long as the ownership model is clear and the owner
|
|
74
|
+
* // remembers to free it
|
|
75
|
+
* const fooRef = makeFooRef(getFoo());
|
|
76
|
+
*
|
|
77
|
+
* // free the foo object when it is no longer needed
|
|
78
|
+
* fooRef.free();
|
|
79
|
+
*
|
|
80
|
+
* ## Updating the reference
|
|
81
|
+
* The `set` method will update the reference and free the old one if exists
|
|
82
|
+
* ```
|
|
83
|
+
* const fooRef = makeFooRef(getFoo());
|
|
84
|
+
* fooRef.set(getFoo()); // the old one will be freed, unless it is the same as the new one
|
|
85
|
+
* ```
|
|
86
|
+
*
|
|
87
|
+
* This has a major pitfall: If the ExternalWeakRef is shared, the new object will be accessible
|
|
88
|
+
* by code that has the old reference. In other words, when the reference is updated, code that
|
|
89
|
+
* already has the old reference will not able to know that it has changed.
|
|
90
|
+
*
|
|
91
|
+
* If this is a problem, you should use this pattern instead:
|
|
92
|
+
* ```typescript
|
|
93
|
+
* // track the "current" valid reference
|
|
94
|
+
* let currentRef = makeFooRef(undefined);
|
|
95
|
+
*
|
|
96
|
+
* export const getFooRef = (): FooRef => {
|
|
97
|
+
* // because of this function, many other places can hold
|
|
98
|
+
* // a valid reference to foo
|
|
99
|
+
* return currentRef;
|
|
100
|
+
* }
|
|
101
|
+
*
|
|
102
|
+
* export const updateFooRef = (newFoo: number): void => {
|
|
103
|
+
* // when updating the reference, we create a new weak ref and free the old one
|
|
104
|
+
* if (currentRef.ref === newFoo) {
|
|
105
|
+
* return; // always need to check if old and new are the same, otherwise we will be freeing the new one
|
|
106
|
+
* }
|
|
107
|
+
* const newRef = makeFooRef(newFoo);
|
|
108
|
+
* currentRef.free();
|
|
109
|
+
* currentRef = newRef;
|
|
110
|
+
*
|
|
111
|
+
* // now other places that hold the old reference will see it's freed
|
|
112
|
+
* }
|
|
113
|
+
* ```
|
|
114
|
+
*/
|
|
115
|
+
export const makeExternalWeakRefType = <TUnderlying, TType>({
|
|
116
|
+
marker,
|
|
117
|
+
free,
|
|
118
|
+
}: ExternalWeakRefConstructor<TUnderlying, TType>) => {
|
|
119
|
+
return (
|
|
120
|
+
obj: TUnderlying | undefined,
|
|
121
|
+
): ExternalWeakRef<TUnderlying, TType> => {
|
|
122
|
+
const weakRefObj = {
|
|
123
|
+
type: marker,
|
|
124
|
+
ref: obj,
|
|
125
|
+
free: () => {
|
|
126
|
+
if (weakRefObj.ref !== undefined) {
|
|
127
|
+
free(weakRefObj.ref);
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
set: (value: TUnderlying | undefined) => {
|
|
131
|
+
if (weakRefObj.ref !== undefined && weakRefObj.ref !== value) {
|
|
132
|
+
free(weakRefObj.ref);
|
|
133
|
+
}
|
|
134
|
+
weakRefObj.ref = value;
|
|
135
|
+
},
|
|
136
|
+
};
|
|
137
|
+
return weakRefObj;
|
|
138
|
+
};
|
|
139
|
+
};
|
package/src/pref/dark.ts
CHANGED
package/src/pref/locale.ts
CHANGED
package/src/sync/index.ts
CHANGED
|
@@ -13,8 +13,6 @@ export {
|
|
|
13
13
|
export { latest, type LatestConstructor, type UpdateArgsFn } from "./latest.ts";
|
|
14
14
|
export { debounce, type DebounceConstructor } from "./debounce.ts";
|
|
15
15
|
export { batch, type BatchConstructor } from "./batch.ts";
|
|
16
|
-
export { cell, type CellConstructor, type Cell } from "./cell.ts";
|
|
17
|
-
export { persist, type PersistConstructor, type Persist } from "./persist.ts";
|
|
18
16
|
export { once, type OnceConstructor } from "./once.ts";
|
|
19
17
|
|
|
20
18
|
// types
|
|
File without changes
|
|
File without changes
|