Skip to content

Commit 8af9a50

Browse files
committed
Fix memory management symbol access issues for TypeScript 5.2+ compatibility
1 parent 6c137e2 commit 8af9a50

File tree

3 files changed

+72
-39
lines changed

3 files changed

+72
-39
lines changed

packages/wallet/src/memory/auto-dispose.ts

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,10 @@ export class AutoDisposeWrapper<T extends Disposable | AsyncDisposable> implemen
6767
this.onDispose(this.resource);
6868
}
6969

70-
if (typeof this.resource[Symbol.asyncDispose] === 'function') {
71-
await (this.resource as AsyncDisposable)[Symbol.asyncDispose]();
72-
} else if (typeof this.resource[Symbol.dispose] === 'function') {
73-
(this.resource as Disposable)[Symbol.dispose]();
70+
if (typeof (this.resource as any)[Symbol.asyncDispose] === 'function') {
71+
await (this.resource as any)[Symbol.asyncDispose]();
72+
} else if (typeof (this.resource as any)[Symbol.dispose] === 'function') {
73+
(this.resource as any)[Symbol.dispose]();
7474
}
7575

7676
(this.resource as any) = null;
@@ -172,10 +172,10 @@ export class RefCountedResource<T extends Disposable | AsyncDisposable> implemen
172172
await this.onLastRelease(this.resource);
173173
}
174174

175-
if (typeof this.resource[Symbol.asyncDispose] === 'function') {
176-
await (this.resource as AsyncDisposable)[Symbol.asyncDispose]();
177-
} else if (typeof this.resource[Symbol.dispose] === 'function') {
178-
(this.resource as Disposable)[Symbol.dispose]();
175+
if (typeof (this.resource as any)[Symbol.asyncDispose] === 'function') {
176+
await (this.resource as any)[Symbol.asyncDispose]();
177+
} else if (typeof (this.resource as any)[Symbol.dispose] === 'function') {
178+
(this.resource as any)[Symbol.dispose]();
179179
}
180180
}
181181

@@ -197,7 +197,7 @@ export class RefCountedResource<T extends Disposable | AsyncDisposable> implemen
197197
/**
198198
* Handle for a reference-counted resource
199199
*/
200-
export class RefCountedHandle<T> implements AsyncDisposable {
200+
export class RefCountedHandle<T extends Disposable | AsyncDisposable> implements AsyncDisposable {
201201
private released = false;
202202

203203
constructor(
@@ -314,10 +314,10 @@ export class LazyResource<T extends Disposable | AsyncDisposable> implements Asy
314314
}
315315

316316
if (this.resource) {
317-
if (typeof this.resource[Symbol.asyncDispose] === 'function') {
318-
await (this.resource as AsyncDisposable)[Symbol.asyncDispose]();
319-
} else if (typeof this.resource[Symbol.dispose] === 'function') {
320-
(this.resource as Disposable)[Symbol.dispose]();
317+
if (typeof (this.resource as any)[Symbol.asyncDispose] === 'function') {
318+
await (this.resource as any)[Symbol.asyncDispose]();
319+
} else if (typeof (this.resource as any)[Symbol.dispose] === 'function') {
320+
(this.resource as any)[Symbol.dispose]();
321321
}
322322
this.resource = undefined;
323323
}
@@ -456,18 +456,18 @@ export class ResourcePool<T extends Disposable | AsyncDisposable> implements Asy
456456
* Dispose a single resource
457457
*/
458458
private async disposeResource(resource: T): Promise<void> {
459-
if (typeof resource[Symbol.asyncDispose] === 'function') {
460-
await (resource as AsyncDisposable)[Symbol.asyncDispose]();
461-
} else if (typeof resource[Symbol.dispose] === 'function') {
462-
(resource as Disposable)[Symbol.dispose]();
459+
if (typeof (resource as any)[Symbol.asyncDispose] === 'function') {
460+
await (resource as any)[Symbol.asyncDispose]();
461+
} else if (typeof (resource as any)[Symbol.dispose] === 'function') {
462+
(resource as any)[Symbol.dispose]();
463463
}
464464
}
465465
}
466466

467467
/**
468468
* Wrapper for a pooled resource
469469
*/
470-
export class PooledResource<T> implements AsyncDisposable {
470+
export class PooledResource<T extends Disposable | AsyncDisposable> implements AsyncDisposable {
471471
private returned = false;
472472

473473
constructor(

packages/wallet/src/memory/resource-scope.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,13 @@ export class HierarchicalResourceScope implements AsyncDisposable {
9898
return await operation(this);
9999
}
100100

101+
/**
102+
* Get all resource IDs in this scope
103+
*/
104+
protected getAllIds(): string[] {
105+
return Array.from(this.resources.keys());
106+
}
107+
101108
/**
102109
* Dispose this scope and all children
103110
*/
@@ -145,10 +152,10 @@ export class HierarchicalResourceScope implements AsyncDisposable {
145152
* Dispose a single resource
146153
*/
147154
private async disposeResource(resource: Disposable | AsyncDisposable): Promise<void> {
148-
if (typeof resource[Symbol.asyncDispose] === 'function') {
149-
await (resource as AsyncDisposable)[Symbol.asyncDispose]();
150-
} else if (typeof resource[Symbol.dispose] === 'function') {
151-
(resource as Disposable)[Symbol.dispose]();
155+
if (typeof (resource as any)[Symbol.asyncDispose] === 'function') {
156+
await (resource as any)[Symbol.asyncDispose]();
157+
} else if (typeof (resource as any)[Symbol.dispose] === 'function') {
158+
(resource as any)[Symbol.dispose]();
152159
}
153160
}
154161

@@ -374,7 +381,7 @@ export class TransactionalResourceScope extends HierarchicalResourceScope {
374381
* Commit all resources
375382
*/
376383
commitAll(): void {
377-
for (const id of this.resources.keys()) {
384+
for (const id of this.getAllIds()) {
378385
this.commit(id);
379386
}
380387
}
@@ -397,7 +404,7 @@ export class TransactionalResourceScope extends HierarchicalResourceScope {
397404
}
398405

399406
// Remove uncommitted resources
400-
const uncommitted = Array.from(this.resources.keys()).filter(id => !this.committed.has(id));
407+
const uncommitted = this.getAllIds().filter(id => !this.committed.has(id));
401408
for (const id of uncommitted) {
402409
try {
403410
await this.remove(id);

packages/wallet/src/memory/using-helpers.ts

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ export function createResourceScope(): ResourceScope {
9696
* Resource scope manager for automatic cleanup
9797
*/
9898
export class ResourceScope implements Disposable, AsyncDisposable {
99-
private readonly stack = new AsyncDisposableStack();
99+
private readonly resources: (Disposable | AsyncDisposable)[] = [];
100100
private disposed = false;
101101

102102
/**
@@ -106,7 +106,8 @@ export class ResourceScope implements Disposable, AsyncDisposable {
106106
if (this.disposed) {
107107
throw new Error('ResourceScope has been disposed');
108108
}
109-
return this.stack.use(resource);
109+
this.resources.push(resource);
110+
return resource;
110111
}
111112

112113
/**
@@ -129,7 +130,7 @@ export class ResourceScope implements Disposable, AsyncDisposable {
129130
}
130131
};
131132

132-
this.stack.use(disposable);
133+
this.resources.push(disposable);
133134
}
134135

135136
/**
@@ -149,8 +150,20 @@ export class ResourceScope implements Disposable, AsyncDisposable {
149150
[Symbol.dispose](): void {
150151
if (!this.disposed) {
151152
this.disposed = true;
152-
// Note: This will log warnings for async resources
153-
this.stack[Symbol.dispose]();
153+
// Dispose resources in reverse order
154+
for (let i = this.resources.length - 1; i >= 0; i--) {
155+
const resource = this.resources[i];
156+
try {
157+
if (typeof (resource as any)[Symbol.dispose] === 'function') {
158+
(resource as any)[Symbol.dispose]();
159+
} else if (typeof (resource as any)[Symbol.asyncDispose] === 'function') {
160+
console.warn('Async resource in sync dispose context');
161+
}
162+
} catch (error) {
163+
console.error('Error disposing resource:', error);
164+
}
165+
}
166+
this.resources.length = 0;
154167
}
155168
}
156169

@@ -160,7 +173,20 @@ export class ResourceScope implements Disposable, AsyncDisposable {
160173
async [Symbol.asyncDispose](): Promise<void> {
161174
if (!this.disposed) {
162175
this.disposed = true;
163-
await this.stack[Symbol.asyncDispose]();
176+
// Dispose resources in reverse order
177+
for (let i = this.resources.length - 1; i >= 0; i--) {
178+
const resource = this.resources[i];
179+
try {
180+
if (typeof (resource as any)[Symbol.asyncDispose] === 'function') {
181+
await (resource as any)[Symbol.asyncDispose]();
182+
} else if (typeof (resource as any)[Symbol.dispose] === 'function') {
183+
(resource as any)[Symbol.dispose]();
184+
}
185+
} catch (error) {
186+
console.error('Error disposing resource:', error);
187+
}
188+
}
189+
this.resources.length = 0;
164190
}
165191
}
166192

@@ -175,7 +201,7 @@ export class ResourceScope implements Disposable, AsyncDisposable {
175201
* Get number of resources in scope
176202
*/
177203
get size(): number {
178-
return this.stack.size;
204+
return this.resources.length;
179205
}
180206
}
181207

@@ -224,13 +250,13 @@ export class TemporaryResourceManager {
224250
if (resource) {
225251
this.activeResources.delete(id);
226252

227-
if ('asyncDispose' in resource && typeof resource[Symbol.asyncDispose] === 'function') {
228-
resource[Symbol.asyncDispose]().catch(error => {
253+
if ('asyncDispose' in resource && typeof (resource as any)[Symbol.asyncDispose] === 'function') {
254+
(resource as any)[Symbol.asyncDispose]().catch((error: any) => {
229255
console.warn(`Error disposing async resource ${id}:`, error);
230256
});
231-
} else if ('dispose' in resource && typeof resource[Symbol.dispose] === 'function') {
257+
} else if ('dispose' in resource && typeof (resource as any)[Symbol.dispose] === 'function') {
232258
try {
233-
resource[Symbol.dispose]();
259+
(resource as any)[Symbol.dispose]();
234260
} catch (error) {
235261
console.warn(`Error disposing resource ${id}:`, error);
236262
}
@@ -288,10 +314,10 @@ export class TemporaryResourceManager {
288314
// Dispose all resources
289315
for (const [id, resource] of this.activeResources) {
290316
try {
291-
if ('asyncDispose' in resource && typeof resource[Symbol.asyncDispose] === 'function') {
292-
await resource[Symbol.asyncDispose]();
293-
} else if ('dispose' in resource && typeof resource[Symbol.dispose] === 'function') {
294-
resource[Symbol.dispose]();
317+
if ('asyncDispose' in resource && typeof (resource as any)[Symbol.asyncDispose] === 'function') {
318+
await (resource as any)[Symbol.asyncDispose]();
319+
} else if ('dispose' in resource && typeof (resource as any)[Symbol.dispose] === 'function') {
320+
(resource as any)[Symbol.dispose]();
295321
}
296322
} catch (error) {
297323
errors.push(error instanceof Error ? error : new Error(`Error disposing ${id}: ${error}`));

0 commit comments

Comments
 (0)