@spooky-sync/client-solid2 0.0.1-canary.263 → 0.0.1-canary.264

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/src/index.ts CHANGED
@@ -47,7 +47,11 @@ export { createQuery, useQuery, type CreateQueryResult, type QueryOptions } from
47
47
  export { createPreload } from './lib/create-preload';
48
48
  export type { PreloadOptions, PreloadRefresh } from '@spooky-sync/core';
49
49
  export { useSyncStatus, type UseSyncStatus } from './lib/use-sync-status';
50
- export { useImpersonation, type UseImpersonation } from './lib/use-impersonation';
50
+ export {
51
+ useImpersonation,
52
+ type UseImpersonation,
53
+ type UseImpersonationOptions,
54
+ } from './lib/use-impersonation';
51
55
  export {
52
56
  useSyncActivity,
53
57
  type UseSyncActivity,
@@ -296,6 +300,16 @@ export class SyncedDb<S extends SchemaStructure> {
296
300
  await this.sp00ky.run(backend, path, unproxy(payload), options);
297
301
  }
298
302
 
303
+ /**
304
+ * Tell the client that this app's own impersonation banner is on screen.
305
+ * Only needed with `impersonationBanner: { mode: 'custom' }`; the
306
+ * `useImpersonation({ rendersBanner: true })` hook calls it for you.
307
+ */
308
+ public acknowledgeImpersonationBanner(): void {
309
+ if (!this.sp00ky) throw new Error('SyncedDb not initialized');
310
+ this.sp00ky.acknowledgeImpersonationBanner();
311
+ }
312
+
299
313
  /**
300
314
  * Sign out, clear session and local storage
301
315
  */
@@ -1,8 +1,17 @@
1
- import type { Accessor } from 'solid-js';
1
+ import { createEffect, type Accessor } from 'solid-js';
2
2
  import { useDb } from './context';
3
3
  import { fromSubscription } from './from-subscription';
4
4
  import type { ImpersonationInfo } from '@spooky-sync/core';
5
5
 
6
+ export interface UseImpersonationOptions {
7
+ /**
8
+ * This component renders the app's own impersonation banner. Required with
9
+ * `impersonationBanner: { mode: 'custom' }`: it acknowledges the banner, so
10
+ * the client does not fall back to its built-in one.
11
+ */
12
+ rendersBanner?: boolean;
13
+ }
14
+
6
15
  export interface UseImpersonation {
7
16
  /** The active impersonation, or `null`. */
8
17
  impersonation: Accessor<ImpersonationInfo | null>;
@@ -17,12 +26,17 @@ export interface UseImpersonation {
17
26
  * such as hiding actions an admin should not take on someone's behalf.
18
27
  * Must be used within a `<Sp00kyProvider>`.
19
28
  */
20
- export function useImpersonation(): UseImpersonation {
29
+ export function useImpersonation(options: UseImpersonationOptions = {}): UseImpersonation {
21
30
  const db = useDb();
22
31
  const impersonation = fromSubscription<ImpersonationInfo | null>(
23
32
  (cb) => db.auth.subscribeImpersonation(cb),
24
33
  db.auth.impersonation
25
34
  );
35
+ // Re-acknowledged per session: a new impersonation restarts the client's
36
+ // fallback timer, and this component is what cancels it.
37
+ createEffect(() => {
38
+ if (options.rendersBanner && impersonation()) db.acknowledgeImpersonationBanner();
39
+ });
26
40
  return {
27
41
  impersonation,
28
42
  isImpersonating: () => impersonation() !== null,