@isograph/reference-counted-pointer 0.5.0 → 0.5.1
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/.turbo/turbo-compile-libs.log +9 -2
- package/dist/createReferenceCountedPointer.d.mts +39 -0
- package/dist/createReferenceCountedPointer.d.mts.map +1 -0
- package/dist/createReferenceCountedPointer.d.ts +15 -10
- package/dist/createReferenceCountedPointer.d.ts.map +1 -1
- package/dist/createReferenceCountedPointer.js +81 -103
- package/dist/createReferenceCountedPointer.mjs +84 -0
- package/dist/createReferenceCountedPointer.mjs.map +1 -0
- package/dist/index.d.mts +2 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -17
- package/dist/index.mjs +3 -0
- package/package.json +14 -6
- package/src/createReferenceCountedPointer.ts +6 -6
- package/dist/index.d.ts.map +0 -1
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
../.. | WARN Unsupported engine: wanted: {"node":"22.9.0"} (current: {"node":"v22.21.1","pnpm":"10.15.0"})
|
|
2
2
|
|
|
3
|
-
> @isograph/reference-counted-pointer@0.5.
|
|
4
|
-
>
|
|
3
|
+
> @isograph/reference-counted-pointer@0.5.1 compile-libs /home/runner/work/isograph/isograph/libs/isograph-reference-counted-pointer
|
|
4
|
+
> tsdown
|
|
5
5
|
|
|
6
|
+
[34mℹ[39m tsdown [2mv0.15.10[22m powered by rolldown [2mv1.0.0-beta.44[22m
|
|
7
|
+
[34mℹ[39m Using tsdown config: [4m/home/runner/work/isograph/isograph/tsdown.config.ts[24m
|
|
8
|
+
(node:2982) [MODULE_TYPELESS_PACKAGE_JSON] Warning: Module type of file:///home/runner/work/isograph/isograph/tsdown.config.ts is not specified and it doesn't parse as CommonJS.
|
|
9
|
+
Reparsing as ES module because module syntax was detected. This incurs a performance overhead.
|
|
10
|
+
To eliminate this warning, add "type": "module" to /home/runner/work/isograph/isograph/package.json.
|
|
11
|
+
(Use `node --trace-warnings ...` to show where the warning was created)
|
|
12
|
+
[34mℹ[39m Build start
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { ItemCleanupPair } from "@isograph/disposable-types";
|
|
2
|
+
|
|
3
|
+
//#region src/createReferenceCountedPointer.d.ts
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Create an undisposed reference-counted pointer guarding a given item.
|
|
7
|
+
*
|
|
8
|
+
* Once all reference-counted pointers guarding a given item have been
|
|
9
|
+
* disposed, the underlying item will be disposed.
|
|
10
|
+
*
|
|
11
|
+
* Additional reference-counted pointers guarding the same item can be
|
|
12
|
+
* created by calling cloneIfNotDisposed().
|
|
13
|
+
*
|
|
14
|
+
* ## Structural sharing
|
|
15
|
+
*
|
|
16
|
+
* Reference counted pointers enable reusing disposable items between
|
|
17
|
+
* application states, so-called structural sharing.
|
|
18
|
+
*
|
|
19
|
+
* If state 1 contains a reference counted pointer to an item, in order
|
|
20
|
+
* to transition to state 2, one would first create an additional
|
|
21
|
+
* reference-counted pointer by calling cloneIfNotDisposed, transition
|
|
22
|
+
* to state 2, then clean up state 1 by disposing of its reference-
|
|
23
|
+
* counted pointers. In this transition, at no time were there zero
|
|
24
|
+
* undisposed reference countend pointers to the disposable item, so it
|
|
25
|
+
* was never disposed, and we could reuse it between states.
|
|
26
|
+
*/
|
|
27
|
+
declare function createReferenceCountedPointer<T>(pair: ItemCleanupPair<T>): ItemCleanupPair<ReferenceCountedPointer<T>>;
|
|
28
|
+
interface ReferenceCountedPointer<T> {
|
|
29
|
+
isDisposed(): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Safety: the item returned here is valid for use only as long as the reference
|
|
32
|
+
* counted pointer is not disposed.
|
|
33
|
+
*/
|
|
34
|
+
getItemIfNotDisposed(): T | null;
|
|
35
|
+
cloneIfNotDisposed(): ItemCleanupPair<ReferenceCountedPointer<T>> | null;
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
38
|
+
export { ReferenceCountedPointer, createReferenceCountedPointer };
|
|
39
|
+
//# sourceMappingURL=createReferenceCountedPointer.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createReferenceCountedPointer.d.mts","names":[],"sources":["../src/createReferenceCountedPointer.ts"],"sourcesContent":[],"mappings":";;;;;;AA0BA;;;;;;;AAQA;;;;;;;;;;;;;iBARgB,uCACR,gBAAgB,KACrB,gBAAgB,wBAAwB;UAM1B;;;;;;0BAMS;wBACF,gBAAgB,wBAAwB"}
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { ItemCleanupPair } from "@isograph/disposable-types";
|
|
2
|
+
|
|
3
|
+
//#region src/createReferenceCountedPointer.d.ts
|
|
4
|
+
|
|
2
5
|
/**
|
|
3
6
|
* Create an undisposed reference-counted pointer guarding a given item.
|
|
4
7
|
*
|
|
@@ -21,14 +24,16 @@ import type { ItemCleanupPair } from '@isograph/disposable-types';
|
|
|
21
24
|
* undisposed reference countend pointers to the disposable item, so it
|
|
22
25
|
* was never disposed, and we could reuse it between states.
|
|
23
26
|
*/
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
27
|
+
declare function createReferenceCountedPointer<T>(pair: ItemCleanupPair<T>): ItemCleanupPair<ReferenceCountedPointer<T>>;
|
|
28
|
+
interface ReferenceCountedPointer<T> {
|
|
29
|
+
isDisposed(): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Safety: the item returned here is valid for use only as long as the reference
|
|
32
|
+
* counted pointer is not disposed.
|
|
33
|
+
*/
|
|
34
|
+
getItemIfNotDisposed(): T | null;
|
|
35
|
+
cloneIfNotDisposed(): ItemCleanupPair<ReferenceCountedPointer<T>> | null;
|
|
33
36
|
}
|
|
37
|
+
//#endregion
|
|
38
|
+
export { ReferenceCountedPointer, createReferenceCountedPointer };
|
|
34
39
|
//# sourceMappingURL=createReferenceCountedPointer.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createReferenceCountedPointer.d.ts","
|
|
1
|
+
{"version":3,"file":"createReferenceCountedPointer.d.ts","names":[],"sources":["../src/createReferenceCountedPointer.ts"],"sourcesContent":[],"mappings":";;;;;;AA0BA;;;;;;;AAQA;;;;;;;;;;;;;iBARgB,uCACR,gBAAgB,KACrB,gBAAgB,wBAAwB;UAM1B;;;;;;0BAMS;wBACF,gBAAgB,wBAAwB"}
|
|
@@ -1,106 +1,84 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
exports.createReferenceCountedPointer = createReferenceCountedPointer;
|
|
4
|
-
// TODO cloneIfNotDisposed should also return the underlying item
|
|
1
|
+
|
|
2
|
+
//#region src/createReferenceCountedPointer.ts
|
|
5
3
|
/**
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
4
|
+
* Create an undisposed reference-counted pointer guarding a given item.
|
|
5
|
+
*
|
|
6
|
+
* Once all reference-counted pointers guarding a given item have been
|
|
7
|
+
* disposed, the underlying item will be disposed.
|
|
8
|
+
*
|
|
9
|
+
* Additional reference-counted pointers guarding the same item can be
|
|
10
|
+
* created by calling cloneIfNotDisposed().
|
|
11
|
+
*
|
|
12
|
+
* ## Structural sharing
|
|
13
|
+
*
|
|
14
|
+
* Reference counted pointers enable reusing disposable items between
|
|
15
|
+
* application states, so-called structural sharing.
|
|
16
|
+
*
|
|
17
|
+
* If state 1 contains a reference counted pointer to an item, in order
|
|
18
|
+
* to transition to state 2, one would first create an additional
|
|
19
|
+
* reference-counted pointer by calling cloneIfNotDisposed, transition
|
|
20
|
+
* to state 2, then clean up state 1 by disposing of its reference-
|
|
21
|
+
* counted pointers. In this transition, at no time were there zero
|
|
22
|
+
* undisposed reference countend pointers to the disposable item, so it
|
|
23
|
+
* was never disposed, and we could reuse it between states.
|
|
24
|
+
*/
|
|
27
25
|
function createReferenceCountedPointer(pair) {
|
|
28
|
-
|
|
29
|
-
return originalReferenceCountedPointer.retainIfNotDisposed();
|
|
30
|
-
}
|
|
31
|
-
// N.B. this could implement ReferenceCountedPointer<T>, but it would not be correct to use it
|
|
32
|
-
// as such, since it does not have an associated dispose function that can be called.
|
|
33
|
-
//
|
|
34
|
-
// Note that there is no way, and should be no way, to determine whether the underlying item
|
|
35
|
-
// has been disposed, let alone force it to be disposed! If you need that, you need to keep track
|
|
36
|
-
// of all calls to retainIfNotDisposed.
|
|
37
|
-
class RefCounter {
|
|
38
|
-
/**
|
|
39
|
-
* Private. Do not expose this class directly, as this contructor creates a ReferenceCountedPointer
|
|
40
|
-
* in an invalid state. We must immediately, after creation, call retainIfNotDisposed().
|
|
41
|
-
*/
|
|
42
|
-
constructor([item, dispose]) {
|
|
43
|
-
this.__state = {
|
|
44
|
-
item,
|
|
45
|
-
dispose,
|
|
46
|
-
activeReferenceCount: 0,
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
getIfNotDisposed() {
|
|
50
|
-
return this.__state === null ? null : this.__state.item;
|
|
51
|
-
}
|
|
52
|
-
retainIfNotDisposed() {
|
|
53
|
-
if (this.__state !== null) {
|
|
54
|
-
this.__state.activeReferenceCount++;
|
|
55
|
-
const activeReference = new ActiveReference(this);
|
|
56
|
-
let disposed = false;
|
|
57
|
-
const dispose = () => {
|
|
58
|
-
if (disposed) {
|
|
59
|
-
throw new Error('Do not dispose an already-disposed ActiveReference.');
|
|
60
|
-
}
|
|
61
|
-
disposed = true;
|
|
62
|
-
if (activeReference.__original === null) {
|
|
63
|
-
throw new Error('Attempted to dispose an active reference, but it was already disposed. ' +
|
|
64
|
-
'This indicates a bug in reference-counted-pointer.');
|
|
65
|
-
}
|
|
66
|
-
activeReference.__original = null;
|
|
67
|
-
if (this.__state === null) {
|
|
68
|
-
throw new Error('Attempted to dispose, but the underlying reference counted pointer was disposed. ' +
|
|
69
|
-
'This indicates a bug in reference-counted-pointer.');
|
|
70
|
-
}
|
|
71
|
-
this.__state.activeReferenceCount--;
|
|
72
|
-
this.__maybeDispose();
|
|
73
|
-
};
|
|
74
|
-
return [activeReference, dispose];
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
return null;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
__maybeDispose() {
|
|
81
|
-
if (this.__state === null) {
|
|
82
|
-
throw new Error('__maybeDispose was called, but the reference counted pointer was disposed. ' +
|
|
83
|
-
'This indicates a bug in reference-counted-pointer.');
|
|
84
|
-
}
|
|
85
|
-
if (this.__state.activeReferenceCount === 0) {
|
|
86
|
-
this.__state.dispose();
|
|
87
|
-
this.__state = null;
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
class ActiveReference {
|
|
92
|
-
constructor(original) {
|
|
93
|
-
this.__original = original;
|
|
94
|
-
}
|
|
95
|
-
isDisposed() {
|
|
96
|
-
return this.__original === null;
|
|
97
|
-
}
|
|
98
|
-
cloneIfNotDisposed() {
|
|
99
|
-
var _a, _b;
|
|
100
|
-
return (_b = (_a = this.__original) === null || _a === void 0 ? void 0 : _a.retainIfNotDisposed()) !== null && _b !== void 0 ? _b : null;
|
|
101
|
-
}
|
|
102
|
-
getItemIfNotDisposed() {
|
|
103
|
-
var _a, _b;
|
|
104
|
-
return (_b = (_a = this.__original) === null || _a === void 0 ? void 0 : _a.getIfNotDisposed()) !== null && _b !== void 0 ? _b : null;
|
|
105
|
-
}
|
|
26
|
+
return new RefCounter(pair).retainIfNotDisposed();
|
|
106
27
|
}
|
|
28
|
+
var RefCounter = class {
|
|
29
|
+
/**
|
|
30
|
+
* Private. Do not expose this class directly, as this contructor creates a ReferenceCountedPointer
|
|
31
|
+
* in an invalid state. We must immediately, after creation, call retainIfNotDisposed().
|
|
32
|
+
*/
|
|
33
|
+
constructor([item, dispose]) {
|
|
34
|
+
this.__state = {
|
|
35
|
+
item,
|
|
36
|
+
dispose,
|
|
37
|
+
activeReferenceCount: 0
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
getIfNotDisposed() {
|
|
41
|
+
return this.__state == null ? null : this.__state.item;
|
|
42
|
+
}
|
|
43
|
+
retainIfNotDisposed() {
|
|
44
|
+
if (this.__state != null) {
|
|
45
|
+
this.__state.activeReferenceCount++;
|
|
46
|
+
const activeReference = new ActiveReference(this);
|
|
47
|
+
let disposed = false;
|
|
48
|
+
const dispose = () => {
|
|
49
|
+
if (disposed) throw new Error("Do not dispose an already-disposed ActiveReference.");
|
|
50
|
+
disposed = true;
|
|
51
|
+
if (activeReference.__original == null) throw new Error("Attempted to dispose an active reference, but it was already disposed. This indicates a bug in reference-counted-pointer.");
|
|
52
|
+
activeReference.__original = null;
|
|
53
|
+
if (this.__state == null) throw new Error("Attempted to dispose, but the underlying reference counted pointer was disposed. This indicates a bug in reference-counted-pointer.");
|
|
54
|
+
this.__state.activeReferenceCount--;
|
|
55
|
+
this.__maybeDispose();
|
|
56
|
+
};
|
|
57
|
+
return [activeReference, dispose];
|
|
58
|
+
} else return null;
|
|
59
|
+
}
|
|
60
|
+
__maybeDispose() {
|
|
61
|
+
if (this.__state == null) throw new Error("__maybeDispose was called, but the reference counted pointer was disposed. This indicates a bug in reference-counted-pointer.");
|
|
62
|
+
if (this.__state.activeReferenceCount === 0) {
|
|
63
|
+
this.__state.dispose();
|
|
64
|
+
this.__state = null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
var ActiveReference = class {
|
|
69
|
+
constructor(original) {
|
|
70
|
+
this.__original = original;
|
|
71
|
+
}
|
|
72
|
+
isDisposed() {
|
|
73
|
+
return this.__original == null;
|
|
74
|
+
}
|
|
75
|
+
cloneIfNotDisposed() {
|
|
76
|
+
return this.__original?.retainIfNotDisposed() ?? null;
|
|
77
|
+
}
|
|
78
|
+
getItemIfNotDisposed() {
|
|
79
|
+
return this.__original?.getIfNotDisposed() ?? null;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
//#endregion
|
|
84
|
+
exports.createReferenceCountedPointer = createReferenceCountedPointer;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
//#region src/createReferenceCountedPointer.ts
|
|
2
|
+
/**
|
|
3
|
+
* Create an undisposed reference-counted pointer guarding a given item.
|
|
4
|
+
*
|
|
5
|
+
* Once all reference-counted pointers guarding a given item have been
|
|
6
|
+
* disposed, the underlying item will be disposed.
|
|
7
|
+
*
|
|
8
|
+
* Additional reference-counted pointers guarding the same item can be
|
|
9
|
+
* created by calling cloneIfNotDisposed().
|
|
10
|
+
*
|
|
11
|
+
* ## Structural sharing
|
|
12
|
+
*
|
|
13
|
+
* Reference counted pointers enable reusing disposable items between
|
|
14
|
+
* application states, so-called structural sharing.
|
|
15
|
+
*
|
|
16
|
+
* If state 1 contains a reference counted pointer to an item, in order
|
|
17
|
+
* to transition to state 2, one would first create an additional
|
|
18
|
+
* reference-counted pointer by calling cloneIfNotDisposed, transition
|
|
19
|
+
* to state 2, then clean up state 1 by disposing of its reference-
|
|
20
|
+
* counted pointers. In this transition, at no time were there zero
|
|
21
|
+
* undisposed reference countend pointers to the disposable item, so it
|
|
22
|
+
* was never disposed, and we could reuse it between states.
|
|
23
|
+
*/
|
|
24
|
+
function createReferenceCountedPointer(pair) {
|
|
25
|
+
return new RefCounter(pair).retainIfNotDisposed();
|
|
26
|
+
}
|
|
27
|
+
var RefCounter = class {
|
|
28
|
+
/**
|
|
29
|
+
* Private. Do not expose this class directly, as this contructor creates a ReferenceCountedPointer
|
|
30
|
+
* in an invalid state. We must immediately, after creation, call retainIfNotDisposed().
|
|
31
|
+
*/
|
|
32
|
+
constructor([item, dispose]) {
|
|
33
|
+
this.__state = {
|
|
34
|
+
item,
|
|
35
|
+
dispose,
|
|
36
|
+
activeReferenceCount: 0
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
getIfNotDisposed() {
|
|
40
|
+
return this.__state == null ? null : this.__state.item;
|
|
41
|
+
}
|
|
42
|
+
retainIfNotDisposed() {
|
|
43
|
+
if (this.__state != null) {
|
|
44
|
+
this.__state.activeReferenceCount++;
|
|
45
|
+
const activeReference = new ActiveReference(this);
|
|
46
|
+
let disposed = false;
|
|
47
|
+
const dispose = () => {
|
|
48
|
+
if (disposed) throw new Error("Do not dispose an already-disposed ActiveReference.");
|
|
49
|
+
disposed = true;
|
|
50
|
+
if (activeReference.__original == null) throw new Error("Attempted to dispose an active reference, but it was already disposed. This indicates a bug in reference-counted-pointer.");
|
|
51
|
+
activeReference.__original = null;
|
|
52
|
+
if (this.__state == null) throw new Error("Attempted to dispose, but the underlying reference counted pointer was disposed. This indicates a bug in reference-counted-pointer.");
|
|
53
|
+
this.__state.activeReferenceCount--;
|
|
54
|
+
this.__maybeDispose();
|
|
55
|
+
};
|
|
56
|
+
return [activeReference, dispose];
|
|
57
|
+
} else return null;
|
|
58
|
+
}
|
|
59
|
+
__maybeDispose() {
|
|
60
|
+
if (this.__state == null) throw new Error("__maybeDispose was called, but the reference counted pointer was disposed. This indicates a bug in reference-counted-pointer.");
|
|
61
|
+
if (this.__state.activeReferenceCount === 0) {
|
|
62
|
+
this.__state.dispose();
|
|
63
|
+
this.__state = null;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
var ActiveReference = class {
|
|
68
|
+
constructor(original) {
|
|
69
|
+
this.__original = original;
|
|
70
|
+
}
|
|
71
|
+
isDisposed() {
|
|
72
|
+
return this.__original == null;
|
|
73
|
+
}
|
|
74
|
+
cloneIfNotDisposed() {
|
|
75
|
+
return this.__original?.retainIfNotDisposed() ?? null;
|
|
76
|
+
}
|
|
77
|
+
getItemIfNotDisposed() {
|
|
78
|
+
return this.__original?.getIfNotDisposed() ?? null;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
//#endregion
|
|
83
|
+
export { createReferenceCountedPointer };
|
|
84
|
+
//# sourceMappingURL=createReferenceCountedPointer.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createReferenceCountedPointer.mjs","names":[],"sources":["../src/createReferenceCountedPointer.ts"],"sourcesContent":["import type { CleanupFn, ItemCleanupPair } from '@isograph/disposable-types';\n\n// TODO cloneIfNotDisposed should also return the underlying item\n\n/**\n * Create an undisposed reference-counted pointer guarding a given item.\n *\n * Once all reference-counted pointers guarding a given item have been\n * disposed, the underlying item will be disposed.\n *\n * Additional reference-counted pointers guarding the same item can be\n * created by calling cloneIfNotDisposed().\n *\n * ## Structural sharing\n *\n * Reference counted pointers enable reusing disposable items between\n * application states, so-called structural sharing.\n *\n * If state 1 contains a reference counted pointer to an item, in order\n * to transition to state 2, one would first create an additional\n * reference-counted pointer by calling cloneIfNotDisposed, transition\n * to state 2, then clean up state 1 by disposing of its reference-\n * counted pointers. In this transition, at no time were there zero\n * undisposed reference countend pointers to the disposable item, so it\n * was never disposed, and we could reuse it between states.\n */\nexport function createReferenceCountedPointer<T>(\n pair: ItemCleanupPair<T>,\n): ItemCleanupPair<ReferenceCountedPointer<T>> {\n const originalReferenceCountedPointer = new RefCounter(pair);\n\n return originalReferenceCountedPointer.retainIfNotDisposed()!;\n}\n\nexport interface ReferenceCountedPointer<T> {\n isDisposed(): boolean;\n /**\n * Safety: the item returned here is valid for use only as long as the reference\n * counted pointer is not disposed.\n */\n getItemIfNotDisposed(): T | null;\n cloneIfNotDisposed(): ItemCleanupPair<ReferenceCountedPointer<T>> | null;\n}\n\ntype RefCountState<T> = {\n item: T;\n dispose: CleanupFn;\n // Invariant: >0\n activeReferenceCount: number;\n};\n\n// N.B. this could implement ReferenceCountedPointer<T>, but it would not be correct to use it\n// as such, since it does not have an associated dispose function that can be called.\n//\n// Note that there is no way, and should be no way, to determine whether the underlying item\n// has been disposed, let alone force it to be disposed! If you need that, you need to keep track\n// of all calls to retainIfNotDisposed.\nclass RefCounter<T> {\n private __state: RefCountState<T> | null;\n\n /**\n * Private. Do not expose this class directly, as this contructor creates a ReferenceCountedPointer\n * in an invalid state. We must immediately, after creation, call retainIfNotDisposed().\n */\n constructor([item, dispose]: ItemCleanupPair<T>) {\n this.__state = {\n item,\n dispose,\n activeReferenceCount: 0,\n };\n }\n\n getIfNotDisposed(): T | null {\n return this.__state == null ? null : this.__state.item;\n }\n\n retainIfNotDisposed(): ItemCleanupPair<ReferenceCountedPointer<T>> | null {\n if (this.__state != null) {\n this.__state.activeReferenceCount++;\n\n const activeReference = new ActiveReference(this);\n\n let disposed = false;\n const dispose = () => {\n if (disposed) {\n throw new Error(\n 'Do not dispose an already-disposed ActiveReference.',\n );\n }\n disposed = true;\n if (activeReference.__original == null) {\n throw new Error(\n 'Attempted to dispose an active reference, but it was already disposed. ' +\n 'This indicates a bug in reference-counted-pointer.',\n );\n }\n activeReference.__original = null;\n if (this.__state == null) {\n throw new Error(\n 'Attempted to dispose, but the underlying reference counted pointer was disposed. ' +\n 'This indicates a bug in reference-counted-pointer.',\n );\n }\n this.__state.activeReferenceCount--;\n this.__maybeDispose();\n };\n\n return [activeReference, dispose];\n } else {\n return null;\n }\n }\n\n private __maybeDispose() {\n if (this.__state == null) {\n throw new Error(\n '__maybeDispose was called, but the reference counted pointer was disposed. ' +\n 'This indicates a bug in reference-counted-pointer.',\n );\n }\n if (this.__state.activeReferenceCount === 0) {\n this.__state.dispose();\n this.__state = null;\n }\n }\n}\n\nclass ActiveReference<T> implements ReferenceCountedPointer<T> {\n // Invariant: __original !== null => the original is not disposed.\n __original: RefCounter<T> | null;\n\n constructor(original: RefCounter<T>) {\n this.__original = original;\n }\n\n isDisposed(): boolean {\n return this.__original == null;\n }\n\n cloneIfNotDisposed(): ItemCleanupPair<ReferenceCountedPointer<T>> | null {\n return this.__original?.retainIfNotDisposed() ?? null;\n }\n\n getItemIfNotDisposed(): T | null {\n return this.__original?.getIfNotDisposed() ?? null;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AA0BA,SAAgB,8BACd,MAC6C;AAG7C,QAFwC,IAAI,WAAW,KAAK,CAErB,qBAAqB;;AA0B9D,IAAM,aAAN,MAAoB;;;;;CAOlB,YAAY,CAAC,MAAM,UAA8B;AAC/C,OAAK,UAAU;GACb;GACA;GACA,sBAAsB;GACvB;;CAGH,mBAA6B;AAC3B,SAAO,KAAK,WAAW,OAAO,OAAO,KAAK,QAAQ;;CAGpD,sBAA0E;AACxE,MAAI,KAAK,WAAW,MAAM;AACxB,QAAK,QAAQ;GAEb,MAAM,kBAAkB,IAAI,gBAAgB,KAAK;GAEjD,IAAI,WAAW;GACf,MAAM,gBAAgB;AACpB,QAAI,SACF,OAAM,IAAI,MACR,sDACD;AAEH,eAAW;AACX,QAAI,gBAAgB,cAAc,KAChC,OAAM,IAAI,MACR,4HAED;AAEH,oBAAgB,aAAa;AAC7B,QAAI,KAAK,WAAW,KAClB,OAAM,IAAI,MACR,sIAED;AAEH,SAAK,QAAQ;AACb,SAAK,gBAAgB;;AAGvB,UAAO,CAAC,iBAAiB,QAAQ;QAEjC,QAAO;;CAIX,AAAQ,iBAAiB;AACvB,MAAI,KAAK,WAAW,KAClB,OAAM,IAAI,MACR,gIAED;AAEH,MAAI,KAAK,QAAQ,yBAAyB,GAAG;AAC3C,QAAK,QAAQ,SAAS;AACtB,QAAK,UAAU;;;;AAKrB,IAAM,kBAAN,MAA+D;CAI7D,YAAY,UAAyB;AACnC,OAAK,aAAa;;CAGpB,aAAsB;AACpB,SAAO,KAAK,cAAc;;CAG5B,qBAAyE;AACvE,SAAO,KAAK,YAAY,qBAAqB,IAAI;;CAGnD,uBAAiC;AAC/B,SAAO,KAAK,YAAY,kBAAkB,IAAI"}
|
package/dist/index.d.mts
ADDED
package/dist/index.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import { ReferenceCountedPointer, createReferenceCountedPointer } from "./createReferenceCountedPointer.js";
|
|
2
|
+
export { ReferenceCountedPointer, createReferenceCountedPointer };
|
package/dist/index.js
CHANGED
|
@@ -1,17 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./createReferenceCountedPointer"), exports);
|
|
1
|
+
const require_createReferenceCountedPointer = require('./createReferenceCountedPointer.js');
|
|
2
|
+
|
|
3
|
+
exports.createReferenceCountedPointer = require_createReferenceCountedPointer.createReferenceCountedPointer;
|
package/dist/index.mjs
ADDED
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@isograph/reference-counted-pointer",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Reference counted pointers enable sharing of disposable items.",
|
|
5
5
|
"homepage": "https://isograph.dev",
|
|
6
|
-
"main": "dist/index.js",
|
|
7
|
-
"types": "dist/index.d.ts",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
8
|
"author": "Isograph Labs",
|
|
9
9
|
"license": "MIT",
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@isograph/disposable-types": "0.5.
|
|
11
|
+
"@isograph/disposable-types": "0.5.1"
|
|
12
12
|
},
|
|
13
13
|
"devDependencies": {
|
|
14
14
|
"typescript": "5.6.3"
|
|
@@ -19,9 +19,17 @@
|
|
|
19
19
|
"directory": "libs/isograph-reference-counted-pointer"
|
|
20
20
|
},
|
|
21
21
|
"sideEffects": false,
|
|
22
|
+
"module": "./dist/index.mjs",
|
|
23
|
+
"exports": {
|
|
24
|
+
".": {
|
|
25
|
+
"import": "./dist/index.mjs",
|
|
26
|
+
"require": "./dist/index.js"
|
|
27
|
+
},
|
|
28
|
+
"./package.json": "./package.json"
|
|
29
|
+
},
|
|
22
30
|
"scripts": {
|
|
23
|
-
"compile-libs": "
|
|
24
|
-
"
|
|
31
|
+
"compile-libs": "tsdown",
|
|
32
|
+
"watch-libs": "tsdown --watch",
|
|
25
33
|
"test": "vitest run",
|
|
26
34
|
"test-watch": "vitest watch",
|
|
27
35
|
"coverage": "vitest run --coverage",
|
|
@@ -71,11 +71,11 @@ class RefCounter<T> {
|
|
|
71
71
|
}
|
|
72
72
|
|
|
73
73
|
getIfNotDisposed(): T | null {
|
|
74
|
-
return this.__state
|
|
74
|
+
return this.__state == null ? null : this.__state.item;
|
|
75
75
|
}
|
|
76
76
|
|
|
77
77
|
retainIfNotDisposed(): ItemCleanupPair<ReferenceCountedPointer<T>> | null {
|
|
78
|
-
if (this.__state
|
|
78
|
+
if (this.__state != null) {
|
|
79
79
|
this.__state.activeReferenceCount++;
|
|
80
80
|
|
|
81
81
|
const activeReference = new ActiveReference(this);
|
|
@@ -88,14 +88,14 @@ class RefCounter<T> {
|
|
|
88
88
|
);
|
|
89
89
|
}
|
|
90
90
|
disposed = true;
|
|
91
|
-
if (activeReference.__original
|
|
91
|
+
if (activeReference.__original == null) {
|
|
92
92
|
throw new Error(
|
|
93
93
|
'Attempted to dispose an active reference, but it was already disposed. ' +
|
|
94
94
|
'This indicates a bug in reference-counted-pointer.',
|
|
95
95
|
);
|
|
96
96
|
}
|
|
97
97
|
activeReference.__original = null;
|
|
98
|
-
if (this.__state
|
|
98
|
+
if (this.__state == null) {
|
|
99
99
|
throw new Error(
|
|
100
100
|
'Attempted to dispose, but the underlying reference counted pointer was disposed. ' +
|
|
101
101
|
'This indicates a bug in reference-counted-pointer.',
|
|
@@ -112,7 +112,7 @@ class RefCounter<T> {
|
|
|
112
112
|
}
|
|
113
113
|
|
|
114
114
|
private __maybeDispose() {
|
|
115
|
-
if (this.__state
|
|
115
|
+
if (this.__state == null) {
|
|
116
116
|
throw new Error(
|
|
117
117
|
'__maybeDispose was called, but the reference counted pointer was disposed. ' +
|
|
118
118
|
'This indicates a bug in reference-counted-pointer.',
|
|
@@ -134,7 +134,7 @@ class ActiveReference<T> implements ReferenceCountedPointer<T> {
|
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
isDisposed(): boolean {
|
|
137
|
-
return this.__original
|
|
137
|
+
return this.__original == null;
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
cloneIfNotDisposed(): ItemCleanupPair<ReferenceCountedPointer<T>> | null {
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iCAAiC,CAAC"}
|