@spine-event-engine/auth 2.0.0-snapshot.25 → 2.0.0-snapshot.28

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 (82) hide show
  1. package/README.md +128 -11
  2. package/REFERENCE.md +166 -12
  3. package/dist/gateway/dynamic-unary-forwarder.d.ts +62 -3
  4. package/dist/gateway/dynamic-unary-forwarder.d.ts.map +1 -1
  5. package/dist/gateway/dynamic-unary-forwarder.js +189 -10
  6. package/dist/gateway/dynamic-unary-forwarder.js.map +1 -1
  7. package/dist/gateway/index.d.ts +5 -0
  8. package/dist/gateway/index.d.ts.map +1 -1
  9. package/dist/gateway/index.js +65 -7
  10. package/dist/gateway/index.js.map +1 -1
  11. package/dist/index.d.ts +60 -3
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +4 -0
  14. package/dist/index.js.map +1 -1
  15. package/dist/native/index.d.ts +43 -3
  16. package/dist/native/index.d.ts.map +1 -1
  17. package/dist/native/index.js +178 -32
  18. package/dist/native/index.js.map +1 -1
  19. package/dist/oidc/contracts.d.ts +18 -4
  20. package/dist/oidc/contracts.d.ts.map +1 -1
  21. package/dist/oidc/flow-store.d.ts +143 -0
  22. package/dist/oidc/flow-store.d.ts.map +1 -0
  23. package/dist/oidc/flow-store.js +184 -0
  24. package/dist/oidc/flow-store.js.map +1 -0
  25. package/dist/oidc/index.d.ts +29 -9
  26. package/dist/oidc/index.d.ts.map +1 -1
  27. package/dist/oidc/index.js +611 -152
  28. package/dist/oidc/index.js.map +1 -1
  29. package/dist/oidc/persistent-flow-store.d.ts +117 -0
  30. package/dist/oidc/persistent-flow-store.d.ts.map +1 -0
  31. package/dist/oidc/persistent-flow-store.js +413 -0
  32. package/dist/oidc/persistent-flow-store.js.map +1 -0
  33. package/dist/oidc/records.d.ts +15 -0
  34. package/dist/oidc/records.d.ts.map +1 -0
  35. package/dist/oidc/records.js +91 -0
  36. package/dist/oidc/records.js.map +1 -0
  37. package/dist/providers/index.d.ts +10 -5
  38. package/dist/providers/index.d.ts.map +1 -1
  39. package/dist/providers/index.js +103 -30
  40. package/dist/providers/index.js.map +1 -1
  41. package/dist/request/index.d.ts +3 -0
  42. package/dist/request/index.d.ts.map +1 -1
  43. package/dist/request/index.js +17 -1
  44. package/dist/request/index.js.map +1 -1
  45. package/dist/sessions/cookies.d.ts +46 -8
  46. package/dist/sessions/cookies.d.ts.map +1 -1
  47. package/dist/sessions/cookies.js +269 -47
  48. package/dist/sessions/cookies.js.map +1 -1
  49. package/dist/sessions/opaque-session-store.d.ts +143 -0
  50. package/dist/sessions/opaque-session-store.d.ts.map +1 -0
  51. package/dist/sessions/opaque-session-store.js +185 -0
  52. package/dist/sessions/opaque-session-store.js.map +1 -0
  53. package/dist/sessions/opaque.d.ts +93 -106
  54. package/dist/sessions/opaque.d.ts.map +1 -1
  55. package/dist/sessions/opaque.js +501 -232
  56. package/dist/sessions/opaque.js.map +1 -1
  57. package/dist/sessions/persistent-opaque-session-store.d.ts +105 -0
  58. package/dist/sessions/persistent-opaque-session-store.d.ts.map +1 -0
  59. package/dist/sessions/persistent-opaque-session-store.js +333 -0
  60. package/dist/sessions/persistent-opaque-session-store.js.map +1 -0
  61. package/dist/sessions/persistent-token-revocations.d.ts +90 -0
  62. package/dist/sessions/persistent-token-revocations.d.ts.map +1 -0
  63. package/dist/sessions/persistent-token-revocations.js +422 -0
  64. package/dist/sessions/persistent-token-revocations.js.map +1 -0
  65. package/dist/sessions/session-lifetime.d.ts +67 -0
  66. package/dist/sessions/session-lifetime.d.ts.map +1 -0
  67. package/dist/sessions/session-lifetime.js +165 -0
  68. package/dist/sessions/session-lifetime.js.map +1 -0
  69. package/dist/sessions/session-record.d.ts +15 -0
  70. package/dist/sessions/session-record.d.ts.map +1 -0
  71. package/dist/sessions/session-record.js +109 -0
  72. package/dist/sessions/session-record.js.map +1 -0
  73. package/dist/sessions/signed.d.ts +5 -4
  74. package/dist/sessions/signed.d.ts.map +1 -1
  75. package/dist/sessions/signed.js +212 -74
  76. package/dist/sessions/signed.js.map +1 -1
  77. package/dist/subscriptions/index.d.ts +35 -3
  78. package/dist/subscriptions/index.d.ts.map +1 -1
  79. package/dist/subscriptions/index.js +680 -134
  80. package/dist/subscriptions/index.js.map +1 -1
  81. package/dist/tsconfig.tsbuildinfo +1 -1
  82. package/package.json +20 -6
@@ -0,0 +1,185 @@
1
+ /*
2
+ * Copyright 2026, CodeMatters. All rights reserved.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
5
+ * in compliance with the License. You may obtain a copy of the License at
6
+ *
7
+ * https://www.apache.org/licenses/LICENSE-2.0
8
+ *
9
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
10
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
11
+ * or implied. See the License for the specific language governing permissions and limitations under
12
+ * the License.
13
+ */
14
+ import { clone, equals } from "@bufbuild/protobuf";
15
+ import {} from "@bufbuild/protobuf/wkt";
16
+ import { Time } from "@spine-event-engine/core/time";
17
+ import { OpaqueSessionRecordSchema, } from "@spine-event-engine/proto/auth";
18
+ import { SessionRecords } from "./session-record.js";
19
+ /**
20
+ * Process-local implementation of the same atomic session transitions.
21
+ */
22
+ export class MemoryOpaqueSessionStore {
23
+ #records = new Map();
24
+ #clock;
25
+ #maxSessions;
26
+ #closed = false;
27
+ /**
28
+ * Creates a process-local store with a trusted maintenance clock.
29
+ *
30
+ * @param clock Supplies the latest allowed purge cutoff.
31
+ * @param maxSessions Process-local retained record bound; defaults to 10,000.
32
+ */
33
+ constructor(clock = Time.currentTime, maxSessions = 10_000) {
34
+ if (!Number.isSafeInteger(maxSessions) || maxSessions <= 0)
35
+ throw new RangeError("maxSessions must be a positive safe integer.");
36
+ this.#clock = clock;
37
+ this.#maxSessions = maxSessions;
38
+ }
39
+ /**
40
+ * Returns whether the process-local retained record bound is reached.
41
+ *
42
+ * @returns Whether another insert requires explicit expiry maintenance.
43
+ */
44
+ atCapacity() {
45
+ return this.#records.size >= this.#maxSessions;
46
+ }
47
+ /**
48
+ * Creates a complete session only when its stable reference is absent.
49
+ *
50
+ * @param record Complete session to insert.
51
+ * @param signal Optional cancellation.
52
+ * @returns Whether insertion won.
53
+ */
54
+ insert(record, signal) {
55
+ return this.#run(() => {
56
+ this.#check(signal);
57
+ if (this.#records.has(record.id))
58
+ return false;
59
+ if (this.atCapacity())
60
+ return false;
61
+ SessionRecords.expiry(record);
62
+ this.#records.set(record.id, clone(OpaqueSessionRecordSchema, record));
63
+ return true;
64
+ });
65
+ }
66
+ /**
67
+ * Reads one authoritative session by stable reference.
68
+ *
69
+ * @param id Stable session reference.
70
+ * @param signal Optional cancellation.
71
+ * @returns Detached current record, if present.
72
+ */
73
+ read(id, signal) {
74
+ return this.#run(() => {
75
+ this.#check(signal);
76
+ const record = this.#records.get(id);
77
+ return record === undefined ? undefined : clone(OpaqueSessionRecordSchema, record);
78
+ });
79
+ }
80
+ /**
81
+ * Replaces exactly one expected session record.
82
+ *
83
+ * @param expected Complete record that must still be current.
84
+ * @param next Replacement with the same stable reference.
85
+ * @param signal Optional cancellation.
86
+ * @returns Whether replacement won.
87
+ */
88
+ replace(expected, next, signal) {
89
+ return this.#run(() => {
90
+ this.#check(signal);
91
+ if (expected.id !== next.id)
92
+ throw new Error("Replacement must retain the stable reference.");
93
+ SessionRecords.expiry(next);
94
+ const current = this.#records.get(expected.id);
95
+ if (current === undefined || !equals(OpaqueSessionRecordSchema, current, expected))
96
+ return false;
97
+ this.#records.set(next.id, clone(OpaqueSessionRecordSchema, next));
98
+ return true;
99
+ });
100
+ }
101
+ /**
102
+ * Deletes the current generation behind a stable reference.
103
+ *
104
+ * @param id Stable session reference.
105
+ * @param signal Optional cancellation.
106
+ * @returns Whether a record was removed.
107
+ */
108
+ revoke(id, signal) {
109
+ return this.#run(() => {
110
+ this.#check(signal);
111
+ return this.#records.delete(id);
112
+ });
113
+ }
114
+ /**
115
+ * Deletes only one complete expected record.
116
+ *
117
+ * @param expected Complete record that may be removed.
118
+ * @param signal Optional cancellation.
119
+ * @returns Whether the expected record was removed.
120
+ */
121
+ remove(expected, signal) {
122
+ return this.#run(() => {
123
+ this.#check(signal);
124
+ const current = this.#records.get(expected.id);
125
+ if (current === undefined || !equals(OpaqueSessionRecordSchema, current, expected))
126
+ return false;
127
+ return this.#records.delete(expected.id);
128
+ });
129
+ }
130
+ /**
131
+ * Removes exact deadlines at or before the trusted cutoff.
132
+ *
133
+ * @param cutoff Current-or-earlier exact deadline.
134
+ * @param signal Optional maintenance cancellation.
135
+ * @returns Number of conditionally removed records.
136
+ */
137
+ purgeExpired(cutoff, signal) {
138
+ return this.#run(() => {
139
+ this.#check(signal);
140
+ const valid = SessionRecords.deadline(cutoff);
141
+ if (SessionRecords.compare(valid, SessionRecords.deadline(this.#clock())) > 0)
142
+ throw new RangeError("Purge cutoff cannot be later than the trusted clock.");
143
+ let removed = 0;
144
+ for (const record of this.#records.values()) {
145
+ this.#check(signal);
146
+ if (SessionRecords.compare(SessionRecords.expiry(record), valid) <= 0) {
147
+ this.#records.delete(record.id);
148
+ removed += 1;
149
+ }
150
+ }
151
+ return removed;
152
+ });
153
+ }
154
+ /**
155
+ * Closes and drops the process-local record references.
156
+ *
157
+ * @returns Completion after local records are dropped.
158
+ */
159
+ close() {
160
+ this.#closed = true;
161
+ this.#records.clear();
162
+ return Promise.resolve();
163
+ }
164
+ /**
165
+ * Converts one synchronous memory transition to the asynchronous port.
166
+ *
167
+ * @typeParam T Result produced by the atomic transition.
168
+ * @param action Atomic memory transition.
169
+ * @returns Transition result or rejected failure.
170
+ */
171
+ #run(action) {
172
+ return Promise.resolve().then(action);
173
+ }
174
+ /**
175
+ * Rejects new work after close or cancellation.
176
+ *
177
+ * @param signal Optional operation cancellation.
178
+ */
179
+ #check(signal) {
180
+ if (this.#closed)
181
+ throw new Error("Opaque session store is closed.");
182
+ signal?.throwIfAborted();
183
+ }
184
+ }
185
+ //# sourceMappingURL=opaque-session-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opaque-session-store.js","sourceRoot":"","sources":["../../src/sessions/opaque-session-store.ts"],"names":[],"mappings":"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"}
@@ -1,200 +1,187 @@
1
+ import { type Timestamp } from "@bufbuild/protobuf/wkt";
2
+ import { type OpaqueSessionStore } from "./opaque-session-store.js";
1
3
  import type { AuthenticatedPrincipal, CookieCredential, RequestCredential, ResolvedSession, SessionResolver } from "../index.js";
2
4
  /**
3
- * Clock used to evaluate opaque-session expiry.
5
+ * Trusted millisecond clock for exact application-session validity.
4
6
  */
5
7
  export interface OpaqueSessionClock {
6
8
  /**
7
- * Returns Unix epoch milliseconds as a safe integer in the Protobuf Timestamp range.
8
- * @returns The current milliseconds.
9
+ * Reads a safe Unix epoch millisecond in the Protobuf Timestamp range.
10
+ *
11
+ * @returns Current milliseconds.
9
12
  */
10
13
  now(): number;
11
14
  }
12
15
  /**
13
- * Creates random bytes for an opaque session identifier.
14
- * @param length The required byte length.
15
- * @returns The generated bytes.
16
+ * Creates cryptographic bytes for a stable ID or credential generation.
17
+ *
18
+ * @param length Required byte count.
19
+ * @returns Random bytes that the caller clears after use.
16
20
  */
17
21
  export type OpaqueSessionRandom = (length: number) => Uint8Array;
18
22
  /**
19
- * Construction options for the bounded in-memory opaque-session resolver.
23
+ * Required sealing and lifetime policy with optional replaceable storage.
20
24
  */
21
25
  export interface OpaqueSessionsOptions {
22
26
  /**
23
- * Millisecond clock; each value must be a safe integer in Timestamp range.
27
+ * Store selected for authoritative session transitions; omission selects memory.
24
28
  */
25
- readonly clock?: OpaqueSessionClock;
29
+ readonly store?: OpaqueSessionStore;
26
30
  /**
27
- * Receives exactly `32` and returns exactly 32 random bytes per call.
28
- * Throwing or wrong-length results consume a bounded collision attempt, and
29
- * every returned mutable buffer is zeroed before this resolver returns.
31
+ * Application and purpose binding authenticated into every seal.
30
32
  */
31
- readonly randomBytes?: OpaqueSessionRandom;
33
+ readonly scope: string;
32
34
  /**
33
- * Positive safe session lifetime in milliseconds; defaults to eight hours.
35
+ * Iron-session secret or numeric version-to-secret rotation map.
34
36
  */
35
- readonly ttlMilliseconds?: number;
37
+ readonly password: string | Readonly<Record<string, string>>;
36
38
  /**
37
- * Positive safe retained-session bound; defaults to 10,000.
39
+ * Trusted application clock for exact expiry checks.
38
40
  */
39
- readonly maxSessions?: number;
41
+ readonly clock: OpaqueSessionClock;
40
42
  /**
41
- * Positive safe ID-generation attempt bound; defaults to three.
43
+ * Positive safe lifetime in milliseconds.
44
+ */
45
+ readonly ttlMilliseconds: number;
46
+ /**
47
+ * Optional injected random source for session ID and generation.
48
+ */
49
+ readonly randomBytes?: OpaqueSessionRandom;
50
+ /**
51
+ * Existing bounded retry policy for random-ID collisions; defaults to three.
42
52
  */
43
53
  readonly collisionAttempts?: number;
54
+ /**
55
+ * Memory-only retained-session bound; defaults to 10,000.
56
+ */
57
+ readonly maxSessions?: number;
44
58
  }
45
59
  /**
46
- * Result of creating an opaque session.
60
+ * Issuance outcome, including a sealed cookie on success.
47
61
  */
48
62
  export type OpaqueSessionCreateResult = {
49
63
  /**
50
- * Identifies successful session creation.
64
+ * Successful issuance through the selected store.
51
65
  */
52
66
  readonly kind: "created";
53
67
  /**
54
- * Provides the cookie credential for the created session.
68
+ * Sealed cookie credential.
55
69
  */
56
70
  readonly credential: CookieCredential;
57
71
  /**
58
- * Provides a defensive copy of the created session.
72
+ * Detached resolved session.
59
73
  */
60
74
  readonly session: ResolvedSession;
61
75
  } | {
62
76
  /**
63
- * Identifies rejected session creation.
77
+ * Rejected issuance.
64
78
  */
65
79
  readonly kind: "rejected";
66
80
  /**
67
- * Explains why the session could not be created.
81
+ * Application-level rejection reason.
68
82
  */
69
83
  readonly reason: "capacity-exceeded" | "entropy-exhausted" | "clock-failure" | "closed";
70
84
  };
71
85
  /**
72
- * Result of rotating an opaque session.
86
+ * Rotation outcome, including a newly sealed cookie on success.
73
87
  */
74
88
  export type OpaqueSessionRotateResult = {
75
89
  /**
76
- * Identifies successful session rotation.
90
+ * Successful atomic generation replacement.
77
91
  */
78
92
  readonly kind: "rotated";
79
93
  /**
80
- * Provides the replacement cookie credential.
94
+ * Replacement sealed cookie credential.
81
95
  */
82
96
  readonly credential: CookieCredential;
83
97
  /**
84
- * Provides a defensive copy of the replacement session.
98
+ * Detached replacement session.
85
99
  */
86
100
  readonly session: ResolvedSession;
87
101
  } | {
88
102
  /**
89
- * Identifies rejected session rotation.
103
+ * Rejected rotation.
90
104
  */
91
105
  readonly kind: "rejected";
92
106
  /**
93
- * Explains why the session could not be rotated.
107
+ * Application-level rejection reason.
94
108
  */
95
109
  readonly reason: "not-found" | "expired" | "unsupported-credential" | "entropy-exhausted" | "clock-failure" | "closed";
96
110
  };
97
111
  /**
98
- * Enumeration-safe acknowledgement of an opaque-session logout request.
112
+ * Enumeration-safe logout acknowledgement.
99
113
  */
100
114
  export interface OpaqueSessionLogoutResult {
101
115
  /**
102
- * Confirms that the logout request was accepted.
116
+ * Acknowledges logout without revealing session presence.
103
117
  */
104
118
  readonly kind: "logged-out";
105
119
  }
106
120
  /**
107
- * A bounded, terminal in-memory store of random opaque application sessions.
108
- *
109
- * It is intentionally process-local: applications needing durable or shared
110
- * sessions provide another `SessionResolver` implementation.
121
+ * Sealed opaque credentials backed by atomic stable-reference transitions.
111
122
  */
112
123
  export declare class OpaqueSessions implements SessionResolver {
113
- private readonly records;
114
- private readonly clock;
115
- private readonly random;
116
- private readonly ttlMilliseconds;
117
- private readonly maxSessions;
118
- private readonly collisionAttempts;
119
- private closed;
120
- /**
121
- * Creates a bounded in-memory session store.
122
- * @param options The optional clock, entropy, lifetime, and capacity settings.
123
- */
124
- constructor(options?: OpaqueSessionsOptions);
125
- /**
126
- * Creates a new session unless the terminal or bounded store state rejects it.
127
- * @param principal The authenticated principal to retain.
128
- * @returns The creation outcome and, when accepted, credential and session.
129
- */
130
- create(principal: AuthenticatedPrincipal): Promise<OpaqueSessionCreateResult>;
124
+ #private;
131
125
  /**
132
- * Resolves one currently live cookie credential as a defensive copy.
133
- * @param credentialInput The credential to resolve.
134
- * @returns The live session, or undefined when it is invalid or expired.
126
+ * Binds already validated policy and an authoritative store.
127
+ *
128
+ * @param options Validated session policy.
129
+ * @param store Selected atomic store.
130
+ * @param internalStore Process-local store created by this strategy, if any.
135
131
  */
136
- resolve(credentialInput: RequestCredential): Promise<ResolvedSession | undefined>;
132
+ private constructor();
137
133
  /**
138
- * Updates a live opaque credential without ever retaining both values.
139
- * @param credentialInput The credential to replace.
140
- * @returns The rotation outcome and, when accepted, the replacement values.
134
+ * Validates sealing and lifetime policy before exposing a usable strategy.
135
+ *
136
+ * @param options Required application policy and optional store.
137
+ * @returns Initialized opaque-session strategy.
141
138
  */
142
- rotate(credentialInput: RequestCredential): Promise<OpaqueSessionRotateResult>;
139
+ static create(options: OpaqueSessionsOptions): Promise<OpaqueSessions>;
143
140
  /**
144
- * Deletes a cookie session when present without revealing whether it existed.
145
- * @param credentialInput The credential to invalidate.
146
- * @returns An enumeration-safe logout acknowledgement.
141
+ * Creates one sealed credential after an atomic absent insertion.
142
+ *
143
+ * @param principal Complete authenticated identity.
144
+ * @param signal Optional cancellation.
145
+ * @returns Issuance result; cancellation never returns a credential.
147
146
  */
148
- logout(credentialInput: RequestCredential): Promise<OpaqueSessionLogoutResult>;
147
+ issue(principal: AuthenticatedPrincipal, signal?: AbortSignal): Promise<OpaqueSessionCreateResult>;
149
148
  /**
150
- * Closes the store and drops retained session identity and record references.
151
- * @returns Completes after retained records are dropped.
149
+ * Resolves only the current generation before its exact deadline.
150
+ *
151
+ * @param credentialInput Cookie credential to validate.
152
+ * @param signal Optional cancellation.
153
+ * @returns Detached session, or undefined for invalid or expired credentials.
152
154
  */
153
- close(): Promise<void>;
155
+ resolve(credentialInput: RequestCredential, signal?: AbortSignal): Promise<ResolvedSession | undefined>;
154
156
  /**
155
- * Checks whether the session store has been closed.
156
- * @returns Whether further session operations must be rejected.
157
+ * Creates a new generation before atomically replacing the current record.
158
+ *
159
+ * @param credentialInput Current cookie credential.
160
+ * @param signal Optional cancellation.
161
+ * @returns One winning replacement or a rejection.
157
162
  */
158
- private isClosed;
163
+ rotate(credentialInput: RequestCredential, signal?: AbortSignal): Promise<OpaqueSessionRotateResult>;
159
164
  /**
160
- * Creates a bounded session record for an authenticated principal.
161
- * @param principal The identity to store in the session.
162
- * @param now The validated issuance time in milliseconds.
163
- * @returns The record, or undefined if expiry cannot be represented.
165
+ * Removes the stable reference when the supplied seal is still live.
166
+ *
167
+ * @param credentialInput Cookie credential to revoke.
168
+ * @param signal Optional cancellation.
169
+ * @returns Enumeration-safe acknowledgement.
164
170
  */
165
- private record;
171
+ logout(credentialInput: RequestCredential, signal?: AbortSignal): Promise<OpaqueSessionLogoutResult>;
166
172
  /**
167
- * Creates an unused opaque credential identifier within the retry limit.
168
- * @returns The identifier, or undefined after entropy failures or collisions.
173
+ * Removes records at or before a trusted maintenance cutoff.
174
+ *
175
+ * @param cutoff Current-or-earlier exact deadline.
176
+ * @param signal Optional maintenance cancellation.
177
+ * @returns Number of conditionally removed records.
169
178
  */
170
- private nextId;
179
+ purgeExpired(cutoff: Timestamp, signal?: AbortSignal): Promise<number>;
171
180
  /**
172
- * Returns a live session record and removes it when expired.
173
- * @param id The opaque credential identifier.
174
- * @param now The validated lookup time in milliseconds.
175
- * @returns The live record, or undefined if absent or expired.
181
+ * Closes new work and drains admitted work and compensation.
182
+ *
183
+ * @returns Repeatable close completion; injected stores remain open.
176
184
  */
177
- private live;
178
- /**
179
- * Removes every session that has expired by the supplied time.
180
- * @param now The validated sweep time in milliseconds.
181
- */
182
- private sweepExpired;
183
- /**
184
- * Compares a session expiry with the current millisecond reading.
185
- * @param record The session record to inspect.
186
- * @param now The validated current time.
187
- * @returns Whether the record has expired.
188
- */
189
- private expired;
190
- /**
191
- * Reads a safe clock value and closes the store on clock failure.
192
- * @returns Current epoch milliseconds, or undefined after failure.
193
- */
194
- private now;
195
- /**
196
- * Closes the store and clears session records after a clock fault.
197
- */
198
- private failClosed;
185
+ close(): Promise<void>;
199
186
  }
200
187
  //# sourceMappingURL=opaque.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"opaque.d.ts","sourceRoot":"","sources":["../../src/sessions/opaque.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"opaque.d.ts","sourceRoot":"","sources":["../../src/sessions/opaque.ts"],"names":[],"mappings":"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"}