@@ -7,6 +7,14 @@ import {getEnv} from '../utils/getEnv'
7
7
8
8
const resourceCache = new WeakMap < SdkIdentity , Map < string , InitializedResource < unknown > > > ( )
9
9
10
+ // Create a singleton identity for the shared auth store
11
+ const SHARED_IDENTITY : SdkIdentity = {
12
+ id : 'shared' ,
13
+ resourceId : 'shared.shared' ,
14
+ projectId : 'shared' ,
15
+ dataset : 'shared' ,
16
+ } as const
17
+
10
18
type Teardown = ( ) => void
11
19
12
20
export interface Resource < TState > {
@@ -16,6 +24,7 @@ export interface Resource<TState> {
16
24
this : { instance : SanityInstance ; state : ResourceState < TState > } ,
17
25
instance : SanityInstance ,
18
26
) => Teardown
27
+ isShared ?: boolean
19
28
}
20
29
21
30
export function createResource < TState > ( resource : Resource < TState > ) : Resource < TState > {
@@ -62,8 +71,9 @@ export function initializeResource<TState>(
62
71
instance : SanityInstance ,
63
72
resource : Resource < TState > ,
64
73
) : InitializedResource < TState > {
65
- const fullName =
66
- resource . name === 'Auth' ? 'Auth-global' : `${ resource . name } -${ instance . identity . resourceId } `
74
+ const fullName = resource . isShared
75
+ ? `${ resource . name } -shared`
76
+ : `${ resource . name } -${ instance . identity . resourceId } `
67
77
const initialState = resource . getInitialState ( instance )
68
78
const state = createResourceState ( initialState , {
69
79
name : fullName ,
@@ -74,16 +84,30 @@ export function initializeResource<TState>(
74
84
return { state, dispose}
75
85
}
76
86
87
+ // Track which instances are using which shared resources
88
+ const instanceSharedResources = new Map < SdkIdentity , Set < string > > ( )
89
+
77
90
export function getOrCreateResource < TState > (
78
91
instance : SanityInstance ,
79
92
resource : Resource < TState > ,
80
93
) : InitializedResource < TState > {
81
- const fullName =
82
- resource . name === 'Auth' ? 'Auth-global' : `${ resource . name } -${ instance . identity . resourceId } `
83
- if ( ! resourceCache . has ( instance . identity ) ) {
84
- resourceCache . set ( instance . identity , new Map ( ) )
94
+ const identityKey = resource . isShared ? SHARED_IDENTITY : instance . identity
95
+ const fullName = resource . isShared
96
+ ? `${ resource . name } -shared`
97
+ : `${ resource . name } -${ instance . identity . resourceId } `
98
+
99
+ if ( resource . isShared ) {
100
+ // Track that this instance is using this shared resource
101
+ if ( ! instanceSharedResources . has ( instance . identity ) ) {
102
+ instanceSharedResources . set ( instance . identity , new Set ( ) )
103
+ }
104
+ instanceSharedResources . get ( instance . identity ) ! . add ( fullName )
85
105
}
86
- const initializedResources = resourceCache . get ( instance . identity ) !
106
+
107
+ if ( ! resourceCache . has ( identityKey ) ) {
108
+ resourceCache . set ( identityKey , new Map ( ) )
109
+ }
110
+ const initializedResources = resourceCache . get ( identityKey ) !
87
111
const cached = initializedResources . get ( fullName )
88
112
if ( cached ) return cached as InitializedResource < TState >
89
113
@@ -93,10 +117,50 @@ export function getOrCreateResource<TState>(
93
117
}
94
118
95
119
export function disposeResources ( identity : SdkIdentity ) : void {
120
+ // Handle instance-specific resources (not shared)
96
121
const resources = resourceCache . get ( identity )
97
- if ( ! resources ) return
122
+ if ( resources ) {
123
+ for ( const resource of resources . values ( ) ) {
124
+ resource . dispose ( )
125
+ }
126
+ resourceCache . delete ( identity )
127
+ }
128
+
129
+ // Handle shared resources this instance may have been using
130
+ const usedSharedResources = instanceSharedResources . get ( identity )
131
+ if ( usedSharedResources ) {
132
+ const sharedResources = resourceCache . get ( SHARED_IDENTITY )
133
+ if ( sharedResources ) {
134
+ for ( const fullName of usedSharedResources ) {
135
+ const resource = sharedResources . get ( fullName )
136
+ if ( resource ) {
137
+ // Remove this instance from tracking
138
+ usedSharedResources . delete ( fullName )
139
+
140
+ // Check if any other instances are still using this shared resource
141
+ let stillInUse = false
142
+ for ( const [ otherIdentity , otherUsed ] of instanceSharedResources . entries ( ) ) {
143
+ if ( otherIdentity !== identity && otherUsed . has ( fullName ) ) {
144
+ stillInUse = true
145
+ break
146
+ }
147
+ }
148
+
149
+ // If no other instances are using it, dispose and clean up
150
+ if ( ! stillInUse ) {
151
+ resource . dispose ( )
152
+ sharedResources . delete ( fullName )
153
+ }
154
+ }
155
+ }
156
+
157
+ // Clean up shared resources map if empty
158
+ if ( sharedResources . size === 0 ) {
159
+ resourceCache . delete ( SHARED_IDENTITY )
160
+ }
161
+ }
98
162
99
- for ( const resource of resources . values ( ) ) {
100
- resource . dispose ( )
163
+ // Clean up instance tracking
164
+ instanceSharedResources . delete ( identity )
101
165
}
102
166
}
0 commit comments