@@ -142,11 +142,9 @@ export interface StoreOptions<T> {
142142 /**
143143 * If set to true, will override the store at the pointer's address if it exists.
144144 *
145- * @remark
146- * Has no effect if the address is unallocated.
147- *
148- * @default false
145+ * *Has no effect if the address is unallocated.*
149146 *
147+ * @default undefined
150148 * @optional
151149 */
152150 override ?: boolean ;
@@ -160,7 +158,7 @@ export interface StoreOptions<T> {
160158 *
161159 * **If no pointer is provided, a pointer will be assigned and returned.**
162160 *
163- * ### Example
161+ * ## Example
164162 *
165163 * ```typescript
166164 * // 1. Creating a store without any options
@@ -205,7 +203,7 @@ export function useStore<T>(state: T, options?: StoreOptions<T>): Pointer {
205203 store . attach ( observer ) ;
206204 }
207205
208- Stores . addStoreAtPointer ( store , pointer , true , false ) ;
206+ Stores . addStoreAtPointer ( store , pointer , { override : true } ) ;
209207 } else {
210208 // If a store exists at address, it will NOT be overrided, but additional observers will be attached to the store.
211209
@@ -220,69 +218,138 @@ export function useStore<T>(state: T, options?: StoreOptions<T>): Pointer {
220218 }
221219}
222220
221+ /**
222+ * Convenience type for `Store` of any type.
223+ */
223224// deno-lint-ignore no-explicit-any
224225export type AnyStore = Store < any > ;
225226
227+ /**
228+ * @internal
229+ * Structure for the `Store` memory stack.
230+ */
226231interface _StoreStack {
227232 [ key : Pointer ] : AnyStore ;
228233}
229234
235+ /**
236+ * A multi {@link Store} container.
237+ */
230238export class StoreStack {
239+ /**
240+ * Checks if the `StoreStack` is instantiated on `window.stores` and creates it if it's not.
241+ */
231242 static configure ( ) : void {
232243 if ( typeof window . stores === "undefined" || window . stores instanceof StoreStack === false ) {
233244 window . stores = new StoreStack ( ) ;
234245 }
235246 }
236247
237- private stores : _StoreStack = { } ;
248+ /**
249+ * @internal
250+ * Object containing all the stores.
251+ */
252+ #stores: _StoreStack = { } ;
238253
254+ /**
255+ * Adds a store to the memory stack and assigns it a pointer.
256+ *
257+ * @param newItem The {@link Store} to be added to the stack.
258+ * @returns The {@link Pointer} to the allocated memory for the store.
259+ */
239260 public addStore ( newItem : AnyStore ) : Pointer {
240261 const ptr = crypto . randomUUID ( ) ;
241262
242- this . stores [ ptr ] = newItem ;
263+ this . # stores[ ptr ] = newItem ;
243264 return ptr ;
244265 }
245266
246- public addStoreAtPointer ( newItem : AnyStore , pointer : Pointer , override ?: boolean , verbose ?: boolean ) : void {
247- if ( typeof this . stores [ pointer ] !== "undefined" && ! override ) {
267+ /**
268+ * Adds a store to the specified {@link Pointer}. If a store already exists at the address, an option can be passed to override it.
269+ * If `override` is set to `false`, but the `verbose` option is set to true, and the memory is already allocated, the store will **NOT**
270+ * be overrided, and an error message will output to the console.
271+ *
272+ * @param newItem The {@link Store} to be added to the stack.
273+ * @param pointer The {@link Pointer} to the memory address where the store should be inserted.
274+ * @param options Defines if a store should be overrided if it exists at the `Pointer` and if a verbose error should be returned if override is set to false.
275+ */
276+ public addStoreAtPointer ( newItem : AnyStore , pointer : Pointer , options : { override ?: boolean , verbose ?: boolean } ) : void {
277+ const { override, verbose } = options ;
278+
279+ if ( typeof this . #stores[ pointer ] !== "undefined" && ! override ) {
248280 if ( verbose ) {
249281 return console . warn ( 'Error: Cannot add store at pointer, address is already allocated.' ) ;
250282 } else {
251283 return ;
252284 }
253285 }
254286
255- this . stores [ pointer ] = newItem ;
287+ this . # stores[ pointer ] = newItem ;
256288 }
257289
290+ /**
291+ * This method makes sure a store if instantiated at the {@link Pointer}'s address.
292+ * If no store is instantiated, it will create one holding the `defaultValue` provided.
293+ * Otherwise, it will only attach {@link Observer Observers} if they are provided.
294+ *
295+ * @param defaultValue A default state value to insert if a new store is created.
296+ * @param pointer The {@link Pointer} to the memory address.
297+ * @param observers {@link Observer Observers } to attach to the store.
298+ */
258299 public upsert < T > ( defaultValue : T , pointer : Pointer , ...observers : Observer < T > [ ] ) : void {
259- if ( typeof this . stores [ pointer ] === "undefined" ) {
260- this . stores [ pointer ] = new Store ( defaultValue ) ;
300+ if ( typeof this . # stores[ pointer ] === "undefined" ) {
301+ this . # stores[ pointer ] = new Store ( defaultValue ) ;
261302 }
262303
263304 for ( const observer of observers ) {
264- this . stores [ pointer ] . attach ( observer ) ;
305+ this . # stores[ pointer ] . attach ( observer ) ;
265306 }
266307 }
267308
268- public removeStore ( ptr : Pointer ) : void {
269- if ( typeof this . stores [ ptr ] === "undefined" ) {
270- return console . error ( 'Error: The pointer address points to unallocated memory.' ) ;
309+ /**
310+ * Removes a store from the memory stack. If the {@link Pointer}'s address is unallocated,
311+ * it will output an error message to the `console` if `verbose` option is set to true.
312+ *
313+ * @param ptr The {@link Pointer}'s address of the store.
314+ * @param options If the removal fails, should the function verbose it to the console? Defaults to false.
315+ */
316+ public removeStore ( ptr : Pointer , options : { verbose ?: boolean } ) : void {
317+ if ( typeof this . #stores[ ptr ] === "undefined" ) {
318+ if ( options . verbose ) {
319+ return console . error ( 'Error: The pointer address points to unallocated memory.' ) ;
320+ } else {
321+ return ;
322+ }
271323 }
272324
273- delete this . stores [ ptr ] ;
325+ delete this . # stores[ ptr ] ;
274326 }
275327
328+ /**
329+ * Returns a reference to the store at the address. A type can be passed in order to make the return typed.
330+ *
331+ * ## Example
332+ * ```typescript
333+ * const ptr = useStore(0);
334+ * console.log(Stores.get<number>(ptr).state); // Output: 0
335+ * ```
336+ *
337+ * @param ptr The {@link Pointer} to the store.
338+ * @returns The store if it exists
339+ */
276340 // deno-lint-ignore no-explicit-any
277341 public get < T = any > ( ptr : Pointer ) : Store < T > | undefined {
278- if ( typeof this . stores [ ptr ] !== "undefined" ) {
279- return this . stores [ ptr ] as Store < T > ;
342+ if ( typeof this . # stores[ ptr ] !== "undefined" ) {
343+ return this . # stores[ ptr ] as Store < T > ;
280344 }
281345
282346 return undefined ;
283347 }
284348}
285349
350+ /**
351+ * Convenience constant, provide access to the global `StoreStack` and creates it if it doesn't exist.
352+ */
286353export const Stores : StoreStack = ( function ( ) {
287354 StoreStack . configure ( ) ;
288355 return window . stores ;
0 commit comments