@fuzdev/fuz_app 0.59.0 → 0.61.0

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.
Files changed (151) hide show
  1. package/dist/actions/CLAUDE.md +5 -5
  2. package/dist/actions/action_codegen.d.ts +1 -1
  3. package/dist/actions/action_codegen.js +2 -2
  4. package/dist/actions/action_event_helpers.d.ts +3 -3
  5. package/dist/actions/action_event_helpers.js +8 -8
  6. package/dist/actions/action_event_types.d.ts +3 -3
  7. package/dist/actions/action_event_types.js +3 -3
  8. package/dist/actions/transports_ws_auth_guard.d.ts +2 -2
  9. package/dist/actions/transports_ws_auth_guard.js +3 -3
  10. package/dist/auth/CLAUDE.md +157 -15
  11. package/dist/auth/actor_lookup_action_specs.d.ts +127 -0
  12. package/dist/auth/actor_lookup_action_specs.d.ts.map +1 -0
  13. package/dist/auth/actor_lookup_action_specs.js +93 -0
  14. package/dist/auth/actor_lookup_actions.d.ts +19 -0
  15. package/dist/auth/actor_lookup_actions.d.ts.map +1 -0
  16. package/dist/auth/actor_lookup_actions.js +32 -0
  17. package/dist/auth/actor_lookup_queries.d.ts +44 -0
  18. package/dist/auth/actor_lookup_queries.d.ts.map +1 -0
  19. package/dist/auth/actor_lookup_queries.js +42 -0
  20. package/dist/auth/actor_search_action_specs.d.ts +166 -0
  21. package/dist/auth/actor_search_action_specs.d.ts.map +1 -0
  22. package/dist/auth/actor_search_action_specs.js +139 -0
  23. package/dist/auth/actor_search_actions.d.ts +31 -0
  24. package/dist/auth/actor_search_actions.d.ts.map +1 -0
  25. package/dist/auth/actor_search_actions.js +61 -0
  26. package/dist/auth/actor_search_queries.d.ts +75 -0
  27. package/dist/auth/actor_search_queries.d.ts.map +1 -0
  28. package/dist/auth/actor_search_queries.js +91 -0
  29. package/dist/auth/admin_actions.js +2 -2
  30. package/dist/auth/all_action_spec_registries.d.ts +55 -0
  31. package/dist/auth/all_action_spec_registries.d.ts.map +1 -0
  32. package/dist/auth/all_action_spec_registries.js +59 -0
  33. package/dist/auth/audit_emitter.d.ts +1 -1
  34. package/dist/auth/audit_emitter.js +2 -2
  35. package/dist/auth/audit_log_queries.d.ts +1 -1
  36. package/dist/auth/audit_log_queries.js +3 -3
  37. package/dist/auth/audit_log_routes.d.ts +1 -1
  38. package/dist/auth/audit_log_routes.js +1 -1
  39. package/dist/auth/audit_log_schema.d.ts +5 -5
  40. package/dist/auth/audit_log_schema.js +7 -7
  41. package/dist/auth/auth_ddl.d.ts +7 -0
  42. package/dist/auth/auth_ddl.d.ts.map +1 -1
  43. package/dist/auth/auth_ddl.js +8 -0
  44. package/dist/auth/credential_type_schema.d.ts +1 -1
  45. package/dist/auth/credential_type_schema.js +3 -3
  46. package/dist/auth/grant_path_schema.d.ts +1 -1
  47. package/dist/auth/grant_path_schema.js +3 -3
  48. package/dist/auth/migrations.d.ts +4 -4
  49. package/dist/auth/migrations.d.ts.map +1 -1
  50. package/dist/auth/migrations.js +7 -6
  51. package/dist/auth/role_grant_offer_actions.js +2 -2
  52. package/dist/auth/role_grant_offer_notifications.d.ts +2 -2
  53. package/dist/auth/role_grant_offer_notifications.js +2 -2
  54. package/dist/auth/role_grant_queries.d.ts +21 -0
  55. package/dist/auth/role_grant_queries.d.ts.map +1 -1
  56. package/dist/auth/role_grant_queries.js +31 -0
  57. package/dist/auth/role_schema.d.ts +2 -2
  58. package/dist/auth/role_schema.js +3 -3
  59. package/dist/auth/self_service_role_actions.d.ts +1 -1
  60. package/dist/auth/self_service_role_actions.js +2 -2
  61. package/dist/auth/session_cookie.d.ts +1 -1
  62. package/dist/auth/session_cookie.js +1 -1
  63. package/dist/auth/session_middleware.d.ts +1 -1
  64. package/dist/auth/session_middleware.js +5 -5
  65. package/dist/rate_limiter.d.ts +5 -5
  66. package/dist/rate_limiter.js +6 -6
  67. package/dist/realtime/sse_auth_guard.d.ts +3 -3
  68. package/dist/realtime/sse_auth_guard.js +4 -4
  69. package/dist/server/app_backend.d.ts +3 -3
  70. package/dist/server/app_backend.js +4 -4
  71. package/dist/server/app_server.d.ts +1 -1
  72. package/dist/server/app_server.js +10 -10
  73. package/dist/testing/CLAUDE.md +22 -12
  74. package/dist/testing/admin_integration.js +4 -4
  75. package/dist/testing/app_server.d.ts +1 -1
  76. package/dist/testing/app_server.js +2 -2
  77. package/dist/testing/attack_surface.d.ts +4 -4
  78. package/dist/testing/attack_surface.js +6 -6
  79. package/dist/testing/audit_completeness.js +4 -4
  80. package/dist/testing/data_exposure.d.ts +2 -2
  81. package/dist/testing/data_exposure.js +7 -7
  82. package/dist/testing/db.d.ts +8 -8
  83. package/dist/testing/db.js +11 -11
  84. package/dist/testing/integration.js +4 -4
  85. package/dist/testing/integration_helpers.d.ts +6 -6
  86. package/dist/testing/integration_helpers.js +7 -7
  87. package/dist/testing/rate_limiting.js +4 -4
  88. package/dist/testing/round_trip.js +2 -2
  89. package/dist/testing/rpc_round_trip.js +2 -2
  90. package/dist/testing/schema_generators.d.ts.map +1 -1
  91. package/dist/testing/schema_generators.js +23 -2
  92. package/dist/testing/sse_round_trip.js +2 -2
  93. package/dist/testing/surface_invariants.d.ts +4 -4
  94. package/dist/testing/surface_invariants.js +5 -5
  95. package/dist/ui/AccountSessions.svelte +21 -6
  96. package/dist/ui/AccountSessions.svelte.d.ts.map +1 -1
  97. package/dist/ui/AdminAccounts.svelte +32 -25
  98. package/dist/ui/AdminAccounts.svelte.d.ts.map +1 -1
  99. package/dist/ui/AdminAuditLog.svelte +3 -3
  100. package/dist/ui/AdminInvites.svelte +20 -15
  101. package/dist/ui/AdminOverview.svelte +19 -21
  102. package/dist/ui/AdminOverview.svelte.d.ts.map +1 -1
  103. package/dist/ui/AdminRoleGrantHistory.svelte +3 -3
  104. package/dist/ui/AdminSessions.svelte +19 -21
  105. package/dist/ui/AdminSessions.svelte.d.ts.map +1 -1
  106. package/dist/ui/AdminSettings.svelte +1 -3
  107. package/dist/ui/AdminSettings.svelte.d.ts.map +1 -1
  108. package/dist/ui/CLAUDE.md +123 -69
  109. package/dist/ui/ConfirmButton.svelte +82 -24
  110. package/dist/ui/ConfirmButton.svelte.d.ts +8 -34
  111. package/dist/ui/ConfirmButton.svelte.d.ts.map +1 -1
  112. package/dist/ui/OpenSignupToggle.svelte +6 -4
  113. package/dist/ui/OpenSignupToggle.svelte.d.ts.map +1 -1
  114. package/dist/ui/RoleGrantOfferForm.svelte +4 -4
  115. package/dist/ui/RoleGrantOfferHistory.svelte +3 -3
  116. package/dist/ui/RoleGrantOfferInbox.svelte +10 -6
  117. package/dist/ui/RoleGrantOfferInbox.svelte.d.ts.map +1 -1
  118. package/dist/ui/account_sessions_state.svelte.d.ts +17 -7
  119. package/dist/ui/account_sessions_state.svelte.d.ts.map +1 -1
  120. package/dist/ui/account_sessions_state.svelte.js +32 -33
  121. package/dist/ui/admin_accounts_state.svelte.d.ts +48 -17
  122. package/dist/ui/admin_accounts_state.svelte.d.ts.map +1 -1
  123. package/dist/ui/admin_accounts_state.svelte.js +58 -76
  124. package/dist/ui/admin_invites_state.svelte.d.ts +14 -7
  125. package/dist/ui/admin_invites_state.svelte.d.ts.map +1 -1
  126. package/dist/ui/admin_invites_state.svelte.js +32 -48
  127. package/dist/ui/admin_sessions_state.svelte.d.ts +15 -8
  128. package/dist/ui/admin_sessions_state.svelte.d.ts.map +1 -1
  129. package/dist/ui/admin_sessions_state.svelte.js +30 -47
  130. package/dist/ui/app_settings_state.svelte.d.ts +8 -3
  131. package/dist/ui/app_settings_state.svelte.d.ts.map +1 -1
  132. package/dist/ui/app_settings_state.svelte.js +19 -27
  133. package/dist/ui/async_slot.svelte.d.ts +173 -0
  134. package/dist/ui/async_slot.svelte.d.ts.map +1 -0
  135. package/dist/ui/async_slot.svelte.js +241 -0
  136. package/dist/ui/audit_log_state.svelte.d.ts +8 -2
  137. package/dist/ui/audit_log_state.svelte.d.ts.map +1 -1
  138. package/dist/ui/audit_log_state.svelte.js +19 -18
  139. package/dist/ui/keyed_async_slot.svelte.d.ts +139 -0
  140. package/dist/ui/keyed_async_slot.svelte.d.ts.map +1 -0
  141. package/dist/ui/keyed_async_slot.svelte.js +177 -0
  142. package/dist/ui/role_grant_offers_state.svelte.d.ts +39 -7
  143. package/dist/ui/role_grant_offers_state.svelte.d.ts.map +1 -1
  144. package/dist/ui/role_grant_offers_state.svelte.js +34 -15
  145. package/dist/ui/table_state.svelte.d.ts +10 -7
  146. package/dist/ui/table_state.svelte.d.ts.map +1 -1
  147. package/dist/ui/table_state.svelte.js +11 -8
  148. package/package.json +1 -1
  149. package/dist/ui/loadable.svelte.d.ts +0 -60
  150. package/dist/ui/loadable.svelte.d.ts.map +0 -1
  151. package/dist/ui/loadable.svelte.js +0 -80
@@ -6,71 +6,54 @@
6
6
  * `token_revoke_all`); the listing wraps the `admin_session_list` RPC
7
7
  * method.
8
8
  *
9
+ * Holds one fetch `AsyncSlot` (`list`) plus two `KeyedAsyncSlot`s keyed by
10
+ * `account_id` — `revoke_sessions` and `revoke_tokens`. Per-account
11
+ * concurrent revokes are independent (clicking row B does not abort row A)
12
+ * and per-row errors surface via `revoke_sessions.error(account_id)` /
13
+ * `revoke_tokens.error(account_id)`.
14
+ *
9
15
  * @module
10
16
  */
11
- import { SvelteSet } from 'svelte/reactivity';
12
- import { Loadable } from './loadable.svelte.js';
13
- export class AdminSessionsState extends Loadable {
17
+ import { AsyncSlot } from './async_slot.svelte.js';
18
+ import { KeyedAsyncSlot } from './keyed_async_slot.svelte.js';
19
+ export class AdminSessionsState {
14
20
  #get_rpc;
21
+ list = new AsyncSlot();
22
+ revoke_sessions = new KeyedAsyncSlot();
23
+ revoke_tokens = new KeyedAsyncSlot();
15
24
  sessions = $state.raw([]);
16
- revoking_account_ids = new SvelteSet();
17
- revoking_token_account_ids = new SvelteSet();
18
25
  active_count = $derived(this.sessions.length);
19
26
  constructor(options) {
20
- super();
21
27
  this.#get_rpc = options?.get_rpc ?? (() => null);
22
28
  }
23
29
  /** True when an RPC adapter is wired. `fetch` and the revoke controls no-op without it. */
24
30
  get has_rpc() {
25
31
  return this.#get_rpc() !== null;
26
32
  }
27
- async fetch() {
33
+ #require_rpc() {
28
34
  const rpc = this.#get_rpc();
29
- if (!rpc) {
30
- this.error = 'rpc adapter not wired';
31
- return;
32
- }
33
- await this.run(async () => {
34
- const { sessions } = await rpc.list_sessions();
35
+ if (!rpc)
36
+ throw new Error('rpc adapter not wired');
37
+ return rpc;
38
+ }
39
+ async fetch() {
40
+ await this.list.run(async () => {
41
+ const { sessions } = await this.#require_rpc().list_sessions();
35
42
  this.sessions = sessions;
36
43
  });
37
44
  }
38
- async revoke_all_for_account(account_id) {
39
- const rpc = this.#get_rpc();
40
- if (!rpc) {
41
- this.error = 'rpc adapter not wired';
42
- return;
43
- }
44
- this.revoking_account_ids.add(account_id);
45
- try {
46
- await rpc.session_revoke_all({ account_id });
47
- this.error = null;
45
+ async submit_revoke_sessions(account_id) {
46
+ await this.revoke_sessions.run(account_id, async () => {
47
+ await this.#require_rpc().session_revoke_all({ account_id });
48
+ });
49
+ if (this.revoke_sessions.succeeded(account_id))
48
50
  await this.fetch();
49
- }
50
- catch (e) {
51
- this.error = e instanceof Error ? e.message : 'Failed to revoke sessions';
52
- }
53
- finally {
54
- this.revoking_account_ids.delete(account_id);
55
- }
56
51
  }
57
- async revoke_all_tokens_for_account(account_id) {
58
- const rpc = this.#get_rpc();
59
- if (!rpc) {
60
- this.error = 'rpc adapter not wired';
61
- return;
62
- }
63
- this.revoking_token_account_ids.add(account_id);
64
- try {
65
- await rpc.token_revoke_all({ account_id });
66
- this.error = null;
52
+ async submit_revoke_tokens(account_id) {
53
+ await this.revoke_tokens.run(account_id, async () => {
54
+ await this.#require_rpc().token_revoke_all({ account_id });
55
+ });
56
+ if (this.revoke_tokens.succeeded(account_id))
67
57
  await this.fetch();
68
- }
69
- catch (e) {
70
- this.error = e instanceof Error ? e.message : 'Failed to revoke tokens';
71
- }
72
- finally {
73
- this.revoking_token_account_ids.delete(account_id);
74
- }
75
58
  }
76
59
  }
@@ -5,9 +5,13 @@
5
5
  * `AdminInvitesRpc` / `AuditLogRpc`. Tests can inject plain-function stubs
6
6
  * and consumers adapt their typed RPC client to the same shape.
7
7
  *
8
+ * Holds two `AsyncSlot`s — `list` (the initial fetch) and `update` (the
9
+ * `app_settings_update` write). Slots track status/error; the canonical
10
+ * `settings` lives on the class so consumers don't unwrap `slot.data`.
11
+ *
8
12
  * @module
9
13
  */
10
- import { Loadable } from './loadable.svelte.js';
14
+ import { AsyncSlot } from './async_slot.svelte.js';
11
15
  import type { AppSettingsWithUsernameJson } from '../auth/app_settings_schema.js';
12
16
  import type { AppSettingsGetOutput, AppSettingsUpdateInput, AppSettingsUpdateOutput } from '../auth/admin_action_specs.js';
13
17
  /**
@@ -35,10 +39,11 @@ export interface AppSettingsStateOptions {
35
39
  */
36
40
  get_rpc?: () => AppSettingsRpc | null;
37
41
  }
38
- export declare class AppSettingsState extends Loadable {
42
+ export declare class AppSettingsState {
39
43
  #private;
44
+ readonly list: AsyncSlot<void, string>;
45
+ readonly update: AsyncSlot<void, string>;
40
46
  settings: AppSettingsWithUsernameJson | null;
41
- updating: boolean;
42
47
  constructor(options?: AppSettingsStateOptions);
43
48
  /** True when an RPC adapter is wired. All ops require it. */
44
49
  get has_rpc(): boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"app_settings_state.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/ui/app_settings_state.svelte.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AAC9C,OAAO,KAAK,EAAC,2BAA2B,EAAC,MAAM,gCAAgC,CAAC;AAChF,OAAO,KAAK,EACX,oBAAoB,EACpB,sBAAsB,EACtB,uBAAuB,EACvB,MAAM,+BAA+B,CAAC;AAEvC;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC9B,GAAG,EAAE,MAAM,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACzC,MAAM,EAAE,CAAC,MAAM,EAAE,sBAAsB,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAC;CAC7E;AAED;;;;GAIG;AACH,eAAO,MAAM,wBAAwB;qBAAwB,cAAc,GAAG,IAAI;yBAArB,cAAc,GAAG,IAAI,wBAArB,cAAc,GAAG,IAAI;CAEjF,CAAC;AAEF,MAAM,WAAW,uBAAuB;IACvC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,cAAc,GAAG,IAAI,CAAC;CACtC;AAED,qBAAa,gBAAiB,SAAQ,QAAQ;;IAG7C,QAAQ,EAAE,2BAA2B,GAAG,IAAI,CAAoB;IAChE,QAAQ,UAAqB;gBAEjB,OAAO,CAAC,EAAE,uBAAuB;IAK7C,6DAA6D;IAC7D,IAAI,OAAO,IAAI,OAAO,CAErB;IAEK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAYtB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;CAiBvD"}
1
+ {"version":3,"file":"app_settings_state.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/ui/app_settings_state.svelte.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,EAAC,SAAS,EAAC,MAAM,wBAAwB,CAAC;AACjD,OAAO,KAAK,EAAC,2BAA2B,EAAC,MAAM,gCAAgC,CAAC;AAChF,OAAO,KAAK,EACX,oBAAoB,EACpB,sBAAsB,EACtB,uBAAuB,EACvB,MAAM,+BAA+B,CAAC;AAEvC;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC9B,GAAG,EAAE,MAAM,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACzC,MAAM,EAAE,CAAC,MAAM,EAAE,sBAAsB,KAAK,OAAO,CAAC,uBAAuB,CAAC,CAAC;CAC7E;AAED;;;;GAIG;AACH,eAAO,MAAM,wBAAwB;qBAAwB,cAAc,GAAG,IAAI;yBAArB,cAAc,GAAG,IAAI,wBAArB,cAAc,GAAG,IAAI;CAEjF,CAAC;AAEF,MAAM,WAAW,uBAAuB;IACvC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,cAAc,GAAG,IAAI,CAAC;CACtC;AAED,qBAAa,gBAAgB;;IAG5B,QAAQ,CAAC,IAAI,0BAAyB;IACtC,QAAQ,CAAC,MAAM,0BAAyB;IAExC,QAAQ,EAAE,2BAA2B,GAAG,IAAI,CAAoB;gBAEpD,OAAO,CAAC,EAAE,uBAAuB;IAI7C,6DAA6D;IAC7D,IAAI,OAAO,IAAI,OAAO,CAErB;IAQK,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAOtB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;CAMvD"}
@@ -5,56 +5,48 @@
5
5
  * `AdminInvitesRpc` / `AuditLogRpc`. Tests can inject plain-function stubs
6
6
  * and consumers adapt their typed RPC client to the same shape.
7
7
  *
8
+ * Holds two `AsyncSlot`s — `list` (the initial fetch) and `update` (the
9
+ * `app_settings_update` write). Slots track status/error; the canonical
10
+ * `settings` lives on the class so consumers don't unwrap `slot.data`.
11
+ *
8
12
  * @module
9
13
  */
10
14
  import { create_context } from '@fuzdev/fuz_ui/context_helpers.js';
11
- import { Loadable } from './loadable.svelte.js';
15
+ import { AsyncSlot } from './async_slot.svelte.js';
12
16
  /**
13
17
  * Svelte context carrying the reactive `AppSettingsRpc` accessor. Mirrors
14
18
  * `admin_accounts_rpc_context`. Unset context falls back to `() => null` so
15
19
  * `OpenSignupToggle` mounted outside a provisioner hides gracefully.
16
20
  */
17
21
  export const app_settings_rpc_context = create_context(() => () => null);
18
- export class AppSettingsState extends Loadable {
22
+ export class AppSettingsState {
19
23
  #get_rpc;
24
+ list = new AsyncSlot();
25
+ update = new AsyncSlot();
20
26
  settings = $state.raw(null);
21
- updating = $state.raw(false);
22
27
  constructor(options) {
23
- super();
24
28
  this.#get_rpc = options?.get_rpc ?? (() => null);
25
29
  }
26
30
  /** True when an RPC adapter is wired. All ops require it. */
27
31
  get has_rpc() {
28
32
  return this.#get_rpc() !== null;
29
33
  }
30
- async fetch() {
34
+ #require_rpc() {
31
35
  const rpc = this.#get_rpc();
32
- if (!rpc) {
33
- this.error = 'rpc adapter not wired';
34
- return;
35
- }
36
- await this.run(async () => {
37
- const { settings } = await rpc.get();
36
+ if (!rpc)
37
+ throw new Error('rpc adapter not wired');
38
+ return rpc;
39
+ }
40
+ async fetch() {
41
+ await this.list.run(async () => {
42
+ const { settings } = await this.#require_rpc().get();
38
43
  this.settings = settings;
39
44
  });
40
45
  }
41
46
  async update_open_signup(value) {
42
- const rpc = this.#get_rpc();
43
- if (!rpc) {
44
- this.error = 'rpc adapter not wired';
45
- return;
46
- }
47
- this.updating = true;
48
- this.error = null;
49
- try {
50
- const { settings } = await rpc.update({ open_signup: value });
47
+ await this.update.run(async () => {
48
+ const { settings } = await this.#require_rpc().update({ open_signup: value });
51
49
  this.settings = settings;
52
- }
53
- catch (e) {
54
- this.error = e instanceof Error ? e.message : 'Failed to update settings';
55
- }
56
- finally {
57
- this.updating = false;
58
- }
50
+ });
59
51
  }
60
52
  }
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Composable async-operation slot for Svelte 5 reactive state classes.
3
+ *
4
+ * A state class HOLDS one or more `AsyncSlot`s via composition — one slot
5
+ * per distinct async operation (e.g. `list` + `create` + `revoke`). Each
6
+ * slot tracks the status, payload, and error of its operation
7
+ * independently, so state classes with multiple write paths don't accumulate
8
+ * ad-hoc `creating` / `updating` fields beside a single shared
9
+ * `loading` / `error` pair.
10
+ *
11
+ * Core surface:
12
+ *
13
+ * - **Explicit four-value `status`** — `AsyncStatus` from
14
+ * `@fuzdev/fuz_util/async.js`: `'initial' | 'pending' | 'success' |
15
+ * 'failure'`. `loading: false, error: null` would be ambiguous
16
+ * between "never tried" and "succeeded once and now resting"; the
17
+ * four-value status removes the need for a per-class `submitted` /
18
+ * `hydrated` flag.
19
+ * - **Owns `data: T | undefined`** — the success payload persists
20
+ * across retries (stale-while-revalidate). The sentinel is
21
+ * `undefined` (not `null`) so `null` stays available as a legitimate
22
+ * success value for nullable `T`s. Pass `T = void` for write-only
23
+ * actions whose response isn't worth keeping.
24
+ * - **Supersession via internal `AbortController`** — a second `run()`
25
+ * aborts the first, and superseded results are silently discarded
26
+ * without writing to state. Removes the "in-flight call resolves
27
+ * after the locator advanced" race that locator-style state classes
28
+ * would otherwise need to compensate for.
29
+ * - **`AbortSignal` threaded to the callback** — RPC clients that accept
30
+ * a signal (or `fetch`) get cancellation for free; callers can also
31
+ * pass an external `signal` via {@link RunOptions} to bind the slot's
32
+ * lifetime to a component / page.
33
+ * - **`preserve_error_on_retry`** — opt-in to keeping the previous error
34
+ * visible while a retry is pending (default clears at the start of
35
+ * each `run()`).
36
+ * - **Per-slot `map_error`** — set once in the constructor
37
+ * (`{map_error: to_rpc_error_message}`); every `run()` gets the right
38
+ * normalization without re-passing per call.
39
+ * - **Public `run()`** — slots are composed, not subclassed, so call
40
+ * sites can invoke `state.list.run(...)` directly.
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * class CellsState {
45
+ * readonly list = new AsyncSlot<{cells: ReadonlyArray<CellJson>}>();
46
+ * readonly create = new AsyncSlot<{cell: CellJson}>({map_error: to_rpc_error_message});
47
+ *
48
+ * async fetch() {
49
+ * await this.list.run((signal) => this.#api.cell_list({}, {signal}));
50
+ * }
51
+ *
52
+ * async submit_new(input: CellCreateInput) {
53
+ * const result = await this.create.run(() => this.#api.cell_create(input));
54
+ * if (result) await this.fetch();
55
+ * }
56
+ * }
57
+ * ```
58
+ *
59
+ * @module
60
+ */
61
+ import type { AsyncStatus } from '@fuzdev/fuz_util/async.js';
62
+ export interface AsyncSlotOptions<T, E = string> {
63
+ /**
64
+ * Seed `data` and put the slot in `'success'` before any `run()`. Useful
65
+ * when the page already has the resource in hand (SSR hydration, a
66
+ * mutation response, hand-off from a parent slot).
67
+ */
68
+ initial?: T;
69
+ /**
70
+ * Convert a caught throw into the error value stored in
71
+ * {@link AsyncSlot.error}. Default extracts `Error.message` (falling
72
+ * back to `'Request failed'` for non-Error throws). Pass
73
+ * `to_rpc_error_message` to unwrap JSON-RPC `data.reason` codes.
74
+ */
75
+ map_error?: (e: unknown) => E;
76
+ /**
77
+ * When `true`, the previous `error` / `error_data` survive the start
78
+ * of a new `run()` until the next success (or another failure
79
+ * overwrites them). Useful for retry UX that wants to keep the
80
+ * failure message visible alongside an inline spinner. Default `false`
81
+ * — `run()` clears the error at the start so the pending state reads
82
+ * "no current error."
83
+ */
84
+ preserve_error_on_retry?: boolean;
85
+ }
86
+ export interface RunOptions {
87
+ /**
88
+ * External signal chained into the slot's internal controller. Aborts
89
+ * the in-flight run when fired (alongside automatic supersession by
90
+ * the next `run()` and manual {@link AsyncSlot.abort} calls).
91
+ */
92
+ signal?: AbortSignal;
93
+ }
94
+ /**
95
+ * Reactive container for a single async operation.
96
+ *
97
+ * @typeParam T - The success payload type. Use `void` for write-only
98
+ * actions whose response isn't worth retaining.
99
+ * @typeParam E - The shape of {@link AsyncSlot.error}. Defaults to
100
+ * `string` (set by the default `map_error`). Narrow to a structured
101
+ * type by providing a `map_error` that returns it.
102
+ */
103
+ export declare class AsyncSlot<T = void, E = string> {
104
+ #private;
105
+ status: AsyncStatus;
106
+ data: T | undefined;
107
+ error: E | null;
108
+ /** The raw caught value from the last failed `run()`, for programmatic inspection. */
109
+ error_data: unknown;
110
+ /** Convenience derived: `status === 'initial'`. */
111
+ readonly initial: boolean;
112
+ /** Convenience derived: `status === 'pending'`. */
113
+ readonly loading: boolean;
114
+ /** Convenience derived: `status === 'success'`. */
115
+ readonly succeeded: boolean;
116
+ /** Convenience derived: `status === 'failure'`. */
117
+ readonly failed: boolean;
118
+ constructor(options?: AsyncSlotOptions<T, E>);
119
+ /**
120
+ * Run an async operation. The callback receives an `AbortSignal` it
121
+ * can forward to fetch / RPC clients that support cancellation; the
122
+ * slot also discards superseded results internally even if the
123
+ * callback ignores the signal.
124
+ *
125
+ * Supersession rule: a second `run()` aborts the first's signal AND
126
+ * silently drops its commit if it resolves anyway. So
127
+ * back-to-back-to-back `run()` calls leave only the last call's
128
+ * result in `data`.
129
+ *
130
+ * Abort rule: a `run()` that throws because of its own signal (manual
131
+ * `abort()`, external `options.signal`, OR supersession by another
132
+ * `run()`) does NOT promote to `'failure'`. Manual / external aborts
133
+ * revert status to the previous resolved state (`'initial'` if no
134
+ * `run()` has ever succeeded, `'success'` otherwise). Supersession is
135
+ * handled by the bail-on-mismatch check, leaving the second run's
136
+ * `'pending'` standing.
137
+ *
138
+ * @returns the resolved value on success; `undefined` on failure,
139
+ * abort, or supersession
140
+ */
141
+ run(fn: (signal: AbortSignal) => Promise<T>, options?: RunOptions): Promise<T | undefined>;
142
+ /**
143
+ * Manually abort the in-flight run, if any. Reverts `status`
144
+ * synchronously to the prior resolved state — `'initial'` if no
145
+ * `run()` (or `set()`) has ever succeeded on this slot, `'success'`
146
+ * otherwise. The aborted run's eventual resolution / rejection is
147
+ * dropped without writing to state (the run's `Promise` resolves to
148
+ * `undefined`).
149
+ */
150
+ abort(reason?: unknown): void;
151
+ /**
152
+ * Replace `data` directly and mark the slot `'success'`. For
153
+ * post-mutation hydration where the calling RPC already returned the
154
+ * canonical row (parallels `CellState.set_cell`).
155
+ *
156
+ * Aborts any in-flight `run()` first — without this, the in-flight
157
+ * callback could resolve after `set()` and overwrite the explicit
158
+ * value (the bail-on-mismatch check only fires when `#controller`
159
+ * was rotated).
160
+ *
161
+ * @mutates `this`
162
+ */
163
+ set(data: T): void;
164
+ /**
165
+ * Reset to `'initial'`, clear `data` / `error` / `error_data`, and
166
+ * abort any in-flight run. After `reset()` the slot looks like a
167
+ * fresh instance with no `initial` option.
168
+ *
169
+ * @mutates `this`
170
+ */
171
+ reset(): void;
172
+ }
173
+ //# sourceMappingURL=async_slot.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"async_slot.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/ui/async_slot.svelte.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2DG;AAEH,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,2BAA2B,CAAC;AAE3D,MAAM,WAAW,gBAAgB,CAAC,CAAC,EAAE,CAAC,GAAG,MAAM;IAC9C;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,CAAC;IACZ;;;;;OAKG;IACH,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,KAAK,CAAC,CAAC;IAC9B;;;;;;;OAOG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;CAClC;AAED,MAAM,WAAW,UAAU;IAC1B;;;;OAIG;IACH,MAAM,CAAC,EAAE,WAAW,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,qBAAa,SAAS,CAAC,CAAC,GAAG,IAAI,EAAE,CAAC,GAAG,MAAM;;IAC1C,MAAM,EAAE,WAAW,CAAyB;IAC5C,IAAI,EAAE,CAAC,GAAG,SAAS,CAAwC;IAC3D,KAAK,EAAE,CAAC,GAAG,IAAI,CAAoB;IACnC,sFAAsF;IACtF,UAAU,EAAE,OAAO,CAAoB;IAEvC,mDAAmD;IACnD,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAuC;IAChE,mDAAmD;IACnD,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAuC;IAChE,mDAAmD;IACnD,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAuC;IAClE,mDAAmD;IACnD,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAuC;gBAcnD,OAAO,GAAE,gBAAgB,CAAC,CAAC,EAAE,CAAC,CAAM;IAUhD;;;;;;;;;;;;;;;;;;;;;OAqBG;IACG,GAAG,CACR,EAAE,EAAE,CAAC,MAAM,EAAE,WAAW,KAAK,OAAO,CAAC,CAAC,CAAC,EACvC,OAAO,GAAE,UAAe,GACtB,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;IA8DzB;;;;;;;OAOG;IACH,KAAK,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,IAAI;IAM7B;;;;;;;;;;;OAWG;IACH,GAAG,CAAC,IAAI,EAAE,CAAC,GAAG,IAAI;IASlB;;;;;;OAMG;IACH,KAAK,IAAI,IAAI;CAQb"}
@@ -0,0 +1,241 @@
1
+ /**
2
+ * Composable async-operation slot for Svelte 5 reactive state classes.
3
+ *
4
+ * A state class HOLDS one or more `AsyncSlot`s via composition — one slot
5
+ * per distinct async operation (e.g. `list` + `create` + `revoke`). Each
6
+ * slot tracks the status, payload, and error of its operation
7
+ * independently, so state classes with multiple write paths don't accumulate
8
+ * ad-hoc `creating` / `updating` fields beside a single shared
9
+ * `loading` / `error` pair.
10
+ *
11
+ * Core surface:
12
+ *
13
+ * - **Explicit four-value `status`** — `AsyncStatus` from
14
+ * `@fuzdev/fuz_util/async.js`: `'initial' | 'pending' | 'success' |
15
+ * 'failure'`. `loading: false, error: null` would be ambiguous
16
+ * between "never tried" and "succeeded once and now resting"; the
17
+ * four-value status removes the need for a per-class `submitted` /
18
+ * `hydrated` flag.
19
+ * - **Owns `data: T | undefined`** — the success payload persists
20
+ * across retries (stale-while-revalidate). The sentinel is
21
+ * `undefined` (not `null`) so `null` stays available as a legitimate
22
+ * success value for nullable `T`s. Pass `T = void` for write-only
23
+ * actions whose response isn't worth keeping.
24
+ * - **Supersession via internal `AbortController`** — a second `run()`
25
+ * aborts the first, and superseded results are silently discarded
26
+ * without writing to state. Removes the "in-flight call resolves
27
+ * after the locator advanced" race that locator-style state classes
28
+ * would otherwise need to compensate for.
29
+ * - **`AbortSignal` threaded to the callback** — RPC clients that accept
30
+ * a signal (or `fetch`) get cancellation for free; callers can also
31
+ * pass an external `signal` via {@link RunOptions} to bind the slot's
32
+ * lifetime to a component / page.
33
+ * - **`preserve_error_on_retry`** — opt-in to keeping the previous error
34
+ * visible while a retry is pending (default clears at the start of
35
+ * each `run()`).
36
+ * - **Per-slot `map_error`** — set once in the constructor
37
+ * (`{map_error: to_rpc_error_message}`); every `run()` gets the right
38
+ * normalization without re-passing per call.
39
+ * - **Public `run()`** — slots are composed, not subclassed, so call
40
+ * sites can invoke `state.list.run(...)` directly.
41
+ *
42
+ * @example
43
+ * ```ts
44
+ * class CellsState {
45
+ * readonly list = new AsyncSlot<{cells: ReadonlyArray<CellJson>}>();
46
+ * readonly create = new AsyncSlot<{cell: CellJson}>({map_error: to_rpc_error_message});
47
+ *
48
+ * async fetch() {
49
+ * await this.list.run((signal) => this.#api.cell_list({}, {signal}));
50
+ * }
51
+ *
52
+ * async submit_new(input: CellCreateInput) {
53
+ * const result = await this.create.run(() => this.#api.cell_create(input));
54
+ * if (result) await this.fetch();
55
+ * }
56
+ * }
57
+ * ```
58
+ *
59
+ * @module
60
+ */
61
+ /**
62
+ * Reactive container for a single async operation.
63
+ *
64
+ * @typeParam T - The success payload type. Use `void` for write-only
65
+ * actions whose response isn't worth retaining.
66
+ * @typeParam E - The shape of {@link AsyncSlot.error}. Defaults to
67
+ * `string` (set by the default `map_error`). Narrow to a structured
68
+ * type by providing a `map_error` that returns it.
69
+ */
70
+ export class AsyncSlot {
71
+ status = $state.raw('initial');
72
+ data = $state.raw(undefined);
73
+ error = $state.raw(null);
74
+ /** The raw caught value from the last failed `run()`, for programmatic inspection. */
75
+ error_data = $state.raw(null);
76
+ /** Convenience derived: `status === 'initial'`. */
77
+ initial = $derived(this.status === 'initial');
78
+ /** Convenience derived: `status === 'pending'`. */
79
+ loading = $derived(this.status === 'pending');
80
+ /** Convenience derived: `status === 'success'`. */
81
+ succeeded = $derived(this.status === 'success');
82
+ /** Convenience derived: `status === 'failure'`. */
83
+ failed = $derived(this.status === 'failure');
84
+ #controller = null;
85
+ /**
86
+ * Tracks whether any `run()` or `set()` has ever produced a success
87
+ * result. Used by {@link abort} to revert to `'success'` (vs `'initial'`)
88
+ * — explicit flag instead of inspecting `data` so the discriminator
89
+ * stays correct for `T = void` (where success-`data` is `undefined`)
90
+ * and for nullable `T`s where `null` is a legitimate success value.
91
+ */
92
+ #has_succeeded = false;
93
+ #map_error;
94
+ #preserve_error;
95
+ constructor(options = {}) {
96
+ if (options.initial !== undefined) {
97
+ this.data = options.initial;
98
+ this.status = 'success';
99
+ this.#has_succeeded = true;
100
+ }
101
+ this.#map_error = options.map_error ?? default_map_error;
102
+ this.#preserve_error = options.preserve_error_on_retry ?? false;
103
+ }
104
+ /**
105
+ * Run an async operation. The callback receives an `AbortSignal` it
106
+ * can forward to fetch / RPC clients that support cancellation; the
107
+ * slot also discards superseded results internally even if the
108
+ * callback ignores the signal.
109
+ *
110
+ * Supersession rule: a second `run()` aborts the first's signal AND
111
+ * silently drops its commit if it resolves anyway. So
112
+ * back-to-back-to-back `run()` calls leave only the last call's
113
+ * result in `data`.
114
+ *
115
+ * Abort rule: a `run()` that throws because of its own signal (manual
116
+ * `abort()`, external `options.signal`, OR supersession by another
117
+ * `run()`) does NOT promote to `'failure'`. Manual / external aborts
118
+ * revert status to the previous resolved state (`'initial'` if no
119
+ * `run()` has ever succeeded, `'success'` otherwise). Supersession is
120
+ * handled by the bail-on-mismatch check, leaving the second run's
121
+ * `'pending'` standing.
122
+ *
123
+ * @returns the resolved value on success; `undefined` on failure,
124
+ * abort, or supersession
125
+ */
126
+ async run(fn, options = {}) {
127
+ this.#controller?.abort();
128
+ const controller = new AbortController();
129
+ this.#controller = controller;
130
+ const external = options.signal;
131
+ let external_handler;
132
+ if (external) {
133
+ if (external.aborted) {
134
+ this.abort(external.reason);
135
+ return undefined;
136
+ }
137
+ // Route external abort through the slot's own abort() so the
138
+ // controller-null + status-revert + signal-fire happens
139
+ // atomically (same path as manual abort). Listener is
140
+ // removed in the finally so successful / failing runs don't
141
+ // leak listeners on long-lived external signals.
142
+ external_handler = () => {
143
+ if (this.#controller === controller)
144
+ this.abort(external.reason);
145
+ };
146
+ external.addEventListener('abort', external_handler, { once: true });
147
+ }
148
+ this.status = 'pending';
149
+ if (!this.#preserve_error) {
150
+ this.error = null;
151
+ this.error_data = null;
152
+ }
153
+ try {
154
+ const result = await fn(controller.signal);
155
+ // Bail if this run was superseded or manually aborted —
156
+ // `abort()` nulls `#controller`, so the mismatch fires in
157
+ // both cases. A callback that ignored its signal and
158
+ // resolved anyway has its result dropped silently.
159
+ if (this.#controller !== controller)
160
+ return undefined;
161
+ this.data = result;
162
+ this.error = null;
163
+ this.error_data = null;
164
+ this.status = 'success';
165
+ this.#has_succeeded = true;
166
+ return result;
167
+ }
168
+ catch (e) {
169
+ if (this.#controller !== controller)
170
+ return undefined;
171
+ this.error = this.#map_error(e);
172
+ this.error_data = e;
173
+ this.status = 'failure';
174
+ return undefined;
175
+ }
176
+ finally {
177
+ if (external_handler)
178
+ external?.removeEventListener('abort', external_handler);
179
+ if (this.#controller === controller)
180
+ this.#controller = null;
181
+ }
182
+ }
183
+ /**
184
+ * Abort the in-flight run (if any) and null out the controller field.
185
+ * Shared by {@link abort}, {@link set}, and {@link reset}.
186
+ */
187
+ #clear_controller(reason) {
188
+ this.#controller?.abort(reason);
189
+ this.#controller = null;
190
+ }
191
+ /**
192
+ * Manually abort the in-flight run, if any. Reverts `status`
193
+ * synchronously to the prior resolved state — `'initial'` if no
194
+ * `run()` (or `set()`) has ever succeeded on this slot, `'success'`
195
+ * otherwise. The aborted run's eventual resolution / rejection is
196
+ * dropped without writing to state (the run's `Promise` resolves to
197
+ * `undefined`).
198
+ */
199
+ abort(reason) {
200
+ if (!this.#controller)
201
+ return;
202
+ this.#clear_controller(reason);
203
+ this.status = this.#has_succeeded ? 'success' : 'initial';
204
+ }
205
+ /**
206
+ * Replace `data` directly and mark the slot `'success'`. For
207
+ * post-mutation hydration where the calling RPC already returned the
208
+ * canonical row (parallels `CellState.set_cell`).
209
+ *
210
+ * Aborts any in-flight `run()` first — without this, the in-flight
211
+ * callback could resolve after `set()` and overwrite the explicit
212
+ * value (the bail-on-mismatch check only fires when `#controller`
213
+ * was rotated).
214
+ *
215
+ * @mutates `this`
216
+ */
217
+ set(data) {
218
+ this.#clear_controller();
219
+ this.data = data;
220
+ this.status = 'success';
221
+ this.#has_succeeded = true;
222
+ this.error = null;
223
+ this.error_data = null;
224
+ }
225
+ /**
226
+ * Reset to `'initial'`, clear `data` / `error` / `error_data`, and
227
+ * abort any in-flight run. After `reset()` the slot looks like a
228
+ * fresh instance with no `initial` option.
229
+ *
230
+ * @mutates `this`
231
+ */
232
+ reset() {
233
+ this.#clear_controller();
234
+ this.status = 'initial';
235
+ this.data = undefined;
236
+ this.error = null;
237
+ this.error_data = null;
238
+ this.#has_succeeded = false;
239
+ }
240
+ }
241
+ const default_map_error = (e) => e instanceof Error ? e.message : 'Request failed';
@@ -6,9 +6,13 @@
6
6
  * stream continues to use `EventSource` directly — streams aren't an RPC
7
7
  * concern.
8
8
  *
9
+ * Holds two `AsyncSlot`s — `list` (the main event stream) and
10
+ * `role_grant_history` (the dedicated role-grant history endpoint). Data
11
+ * lives on the class so SSE pushes and gap-fill calls update it directly.
12
+ *
9
13
  * @module
10
14
  */
11
- import { Loadable } from './loadable.svelte.js';
15
+ import { AsyncSlot } from './async_slot.svelte.js';
12
16
  import type { AuditLogEventWithUsernamesJson, RoleGrantHistoryEventJson } from '../auth/audit_log_schema.js';
13
17
  import type { AuditLogListInput, AuditLogListOutput, AuditLogRoleGrantHistoryInput, AuditLogRoleGrantHistoryOutput } from '../auth/admin_action_specs.js';
14
18
  /**
@@ -38,8 +42,10 @@ export interface AuditLogStateOptions {
38
42
  /** SSE stream URL. Defaults to the shipped admin audit-log stream route. */
39
43
  stream_url?: string;
40
44
  }
41
- export declare class AuditLogState extends Loadable {
45
+ export declare class AuditLogState {
42
46
  #private;
47
+ readonly list: AsyncSlot<void, string>;
48
+ readonly role_grant_history: AsyncSlot<void, string>;
43
49
  events: Array<AuditLogEventWithUsernamesJson>;
44
50
  role_grant_history_events: Array<RoleGrantHistoryEventJson>;
45
51
  readonly count: number;
@@ -1 +1 @@
1
- {"version":3,"file":"audit_log_state.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/ui/audit_log_state.svelte.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,EAAC,QAAQ,EAAC,MAAM,sBAAsB,CAAC;AAC9C,OAAO,KAAK,EAEX,8BAA8B,EAC9B,yBAAyB,EACzB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EACX,iBAAiB,EACjB,kBAAkB,EAClB,6BAA6B,EAC7B,8BAA8B,EAC9B,MAAM,+BAA+B,CAAC;AAGvC;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,iBAAiB,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACjE,kBAAkB,EAAE,CACnB,KAAK,CAAC,EAAE,6BAA6B,KACjC,OAAO,CAAC,8BAA8B,CAAC,CAAC;CAC7C;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB;qBAAwB,WAAW,GAAG,IAAI;yBAAlB,WAAW,GAAG,IAAI,wBAAlB,WAAW,GAAG,IAAI;CAAmB,CAAC;AAEhG,MAAM,WAAW,oBAAoB;IACpC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,WAAW,GAAG,IAAI,CAAC;IACnC,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,aAAc,SAAQ,QAAQ;;IAG1C,MAAM,EAAE,KAAK,CAAC,8BAA8B,CAAC,CAAkB;IAC/D,yBAAyB,EAAE,KAAK,CAAC,yBAAyB,CAAC,CAAkB;IAE7E,QAAQ,CAAC,KAAK,SAAgC;IAE9C,qDAAqD;IACrD,SAAS,UAAqB;gBAWlB,OAAO,CAAC,EAAE,oBAAoB;IAM1C,8FAA8F;IAC9F,IAAI,OAAO,IAAI,OAAO,CAErB;IAEK,KAAK,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAajD,wBAAwB,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAY9E;;;;;;;;OAQG;IACH,SAAS,IAAI,MAAM,IAAI;IA0CvB;;;;OAIG;IACH,UAAU,IAAI,IAAI;CAiClB"}
1
+ {"version":3,"file":"audit_log_state.svelte.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/ui/audit_log_state.svelte.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,OAAO,EAAC,SAAS,EAAC,MAAM,wBAAwB,CAAC;AACjD,OAAO,KAAK,EAEX,8BAA8B,EAC9B,yBAAyB,EACzB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EACX,iBAAiB,EACjB,kBAAkB,EAClB,6BAA6B,EAC7B,8BAA8B,EAC9B,MAAM,+BAA+B,CAAC;AAGvC;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC3B,IAAI,EAAE,CAAC,KAAK,CAAC,EAAE,iBAAiB,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACjE,kBAAkB,EAAE,CACnB,KAAK,CAAC,EAAE,6BAA6B,KACjC,OAAO,CAAC,8BAA8B,CAAC,CAAC;CAC7C;AAED;;;GAGG;AACH,eAAO,MAAM,qBAAqB;qBAAwB,WAAW,GAAG,IAAI;yBAAlB,WAAW,GAAG,IAAI,wBAAlB,WAAW,GAAG,IAAI;CAAmB,CAAC;AAEhG,MAAM,WAAW,oBAAoB;IACpC;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,WAAW,GAAG,IAAI,CAAC;IACnC,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,aAAa;;IAGzB,QAAQ,CAAC,IAAI,0BAAyB;IACtC,QAAQ,CAAC,kBAAkB,0BAAyB;IAEpD,MAAM,EAAE,KAAK,CAAC,8BAA8B,CAAC,CAAkB;IAC/D,yBAAyB,EAAE,KAAK,CAAC,yBAAyB,CAAC,CAAkB;IAE7E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAgC;IAEtD,qDAAqD;IACrD,SAAS,UAAqB;gBAWlB,OAAO,CAAC,EAAE,oBAAoB;IAK1C,8FAA8F;IAC9F,IAAI,OAAO,IAAI,OAAO,CAErB;IAQK,KAAK,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC;IAQjD,wBAAwB,CAAC,KAAK,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAO9E;;;;;;;;OAQG;IACH,SAAS,IAAI,MAAM,IAAI;IA0CvB;;;;OAIG;IACH,UAAU,IAAI,IAAI;CAiClB"}