chromium-tabs 0.1.0 → 0.2.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.
- package/README.md +55 -1
- package/dist/chunk-NDM7JYY6.js +40 -0
- package/dist/chunk-NDM7JYY6.js.map +1 -0
- package/dist/{chunk-2DTGNBUT.js → chunk-XUPBZES2.js} +7 -38
- package/dist/chunk-XUPBZES2.js.map +1 -0
- package/dist/command-storage-backend-BLy7EP79.d.cts +318 -0
- package/dist/command-storage-backend-CDoXkRtc.d.ts +318 -0
- package/dist/core/index.d.cts +5 -629
- package/dist/core/index.d.ts +5 -629
- package/dist/core/index.js +7 -5
- package/dist/index.d.cts +5 -2
- package/dist/index.d.ts +5 -2
- package/dist/index.js +7 -5
- package/dist/index.js.map +1 -1
- package/dist/session/index.cjs +1406 -0
- package/dist/session/index.cjs.map +1 -0
- package/dist/session/index.d.cts +479 -0
- package/dist/session/index.d.ts +479 -0
- package/dist/session/index.js +1320 -0
- package/dist/session/index.js.map +1 -0
- package/dist/session/node.cjs +76 -0
- package/dist/session/node.cjs.map +1 -0
- package/dist/session/node.d.cts +34 -0
- package/dist/session/node.d.ts +34 -0
- package/dist/session/node.js +51 -0
- package/dist/session/node.js.map +1 -0
- package/dist/tab-strip-model-DSFYavJO.d.cts +496 -0
- package/dist/tab-strip-model-JBpyUyRs.d.ts +496 -0
- package/dist/types-CYa7ouKw.d.cts +137 -0
- package/dist/types-CYa7ouKw.d.ts +137 -0
- package/package.json +12 -1
- package/dist/chunk-2DTGNBUT.js.map +0 -1
|
@@ -0,0 +1,479 @@
|
|
|
1
|
+
import { C as CommandStorageBackend, S as SessionCommand, R as ReadCommandsResult, a as SessionTab, b as SessionWindow, c as SessionWindowId, d as SessionSnapshot, e as SerializedNavigationEntry } from '../command-storage-backend-BLy7EP79.cjs';
|
|
2
|
+
export { D as DEFAULT_WINDOW_ID, f as SessionCommandId, g as SessionTabGroup, h as createAddTabExtraDataCommand, i as createAddWindowExtraDataCommand, j as createLastActiveTimeCommand, k as createPinnedStateCommand, l as createSetActiveWindowCommand, m as createSetSelectedNavigationIndexCommand, n as createSetSelectedTabInWindowCommand, o as createSetTabDataCommand, p as createSetTabIndexInWindowCommand, q as createSetTabWindowCommand, r as createTabClosedCommand, s as createTabGroupCommand, t as createTabGroupMetadataUpdateCommand, u as createTabNavigationPathPrunedCommand, v as createUpdateTabNavigationCommand, w as createWindowClosedCommand, x as currentNavigationEntry, y as findClosestNavigationWithIndex, z as isClosingCommand, A as processTabNavigationPathPruned, B as restoreSessionFromCommands } from '../command-storage-backend-BLy7EP79.cjs';
|
|
3
|
+
import { T as TabStripModel } from '../tab-strip-model-DSFYavJO.cjs';
|
|
4
|
+
import { d as TabId, T as TabGroupId, b as Tab } from '../types-CYa7ouKw.cjs';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Buffers commands and flushes them to a storage backend on a delay.
|
|
8
|
+
* Ported from chromium-reference/components/sessions/core/command_storage_manager.cc.
|
|
9
|
+
*
|
|
10
|
+
* Chrome posts backend writes to a sequenced task runner; this port chains
|
|
11
|
+
* them on a promise queue so writes land in order even when the backend is
|
|
12
|
+
* asynchronous. Saves snapshot the pending buffer synchronously, exactly
|
|
13
|
+
* like Chrome moving pending_commands_ into the posted task (cc:251).
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/** Delay before pending commands are written. Mirrors kSaveDelay (cc:36). */
|
|
17
|
+
declare const SAVE_DELAY_MS = 2500;
|
|
18
|
+
/** Mirrors CommandStorageManagerDelegate (command_storage_manager_delegate.h). */
|
|
19
|
+
interface CommandStorageManagerDelegate {
|
|
20
|
+
/** Called before each save; a chance to append more commands (cc:255). */
|
|
21
|
+
onWillSaveCommands?(): void;
|
|
22
|
+
/** A backend write failed; schedule a full rebuild (delegate.h:29). */
|
|
23
|
+
onErrorWritingSessionCommands?(): void;
|
|
24
|
+
}
|
|
25
|
+
interface CommandStorageManagerOptions {
|
|
26
|
+
backend: CommandStorageBackend;
|
|
27
|
+
delegate?: CommandStorageManagerDelegate;
|
|
28
|
+
saveDelayMs?: number;
|
|
29
|
+
/**
|
|
30
|
+
* Awaited before the first backend write — the SessionService uses this to
|
|
31
|
+
* make sure the previous session has been rotated to the "last" slot
|
|
32
|
+
* before this session's first (truncating) write can clobber it.
|
|
33
|
+
*/
|
|
34
|
+
ready?: Promise<unknown>;
|
|
35
|
+
}
|
|
36
|
+
declare class CommandStorageManager {
|
|
37
|
+
private readonly backend_;
|
|
38
|
+
private readonly delegate_;
|
|
39
|
+
private readonly saveDelayMs_;
|
|
40
|
+
private pendingCommands_;
|
|
41
|
+
/** Starts true: the first save is always a complete rewrite (cc:117). */
|
|
42
|
+
private pendingReset_;
|
|
43
|
+
private commandsSinceReset_;
|
|
44
|
+
private saveTimer_;
|
|
45
|
+
/** Sequenced "task runner" for backend writes. */
|
|
46
|
+
private queue_;
|
|
47
|
+
/** Backend operations started but not yet settled. */
|
|
48
|
+
private inflight_;
|
|
49
|
+
constructor(options: CommandStorageManagerOptions);
|
|
50
|
+
/**
|
|
51
|
+
* Runs a backend operation. When nothing is in flight it runs inline — a
|
|
52
|
+
* synchronous backend then completes before this returns, which is what
|
|
53
|
+
* makes a pagehide flush reliable (the web stand-in for Chrome's
|
|
54
|
+
* BLOCK_SHUTDOWN task traits). Otherwise it is sequenced behind the queue.
|
|
55
|
+
*/
|
|
56
|
+
private enqueue_;
|
|
57
|
+
get pendingReset(): boolean;
|
|
58
|
+
/** Mirrors set_pending_reset (command_storage_manager.h:77). */
|
|
59
|
+
setPendingReset(value: boolean): void;
|
|
60
|
+
get commandsSinceReset(): number;
|
|
61
|
+
/** Buffers a command and starts the save timer. Mirrors cc:192. */
|
|
62
|
+
scheduleCommand(command: SessionCommand): void;
|
|
63
|
+
/** Buffers rebuild commands without starting the timer. Mirrors cc:207. */
|
|
64
|
+
appendRebuildCommands(commands: readonly SessionCommand[]): void;
|
|
65
|
+
appendRebuildCommand(command: SessionCommand): void;
|
|
66
|
+
/** Removes a not-yet-saved command. Mirrors EraseCommand (cc:216). */
|
|
67
|
+
eraseCommand(command: SessionCommand): void;
|
|
68
|
+
/** Replaces a not-yet-saved command in place. Mirrors SwapCommand (cc:225). */
|
|
69
|
+
swapCommand(oldCommand: SessionCommand, newCommand: SessionCommand): void;
|
|
70
|
+
/** Mirrors ClearPendingCommands (cc:233) — note it does not zero the reset counter. */
|
|
71
|
+
clearPendingCommands(): void;
|
|
72
|
+
/** Read-only view for ReplacePendingCommand-style optimizations. */
|
|
73
|
+
get pendingCommands(): readonly SessionCommand[];
|
|
74
|
+
/** True between startSaveTimer() and the save it scheduled. Mirrors cc:316. */
|
|
75
|
+
get hasPendingSave(): boolean;
|
|
76
|
+
/** Schedules a save in saveDelayMs unless one is already pending. Mirrors cc:239. */
|
|
77
|
+
startSaveTimer(): void;
|
|
78
|
+
/**
|
|
79
|
+
* Flushes pending commands to the backend. Mirrors Save (cc:251): the
|
|
80
|
+
* buffer and reset flag are snapshotted synchronously; the write itself is
|
|
81
|
+
* sequenced behind earlier writes. Returns once this write has settled.
|
|
82
|
+
*/
|
|
83
|
+
save(): Promise<void>;
|
|
84
|
+
/** Cancels any timer and flushes immediately. */
|
|
85
|
+
saveNow(): Promise<void>;
|
|
86
|
+
/**
|
|
87
|
+
* Promotes the current session to "last". Pending commands are flushed
|
|
88
|
+
* first, mirroring MoveCurrentSessionToLastSession (cc:320). The caller is
|
|
89
|
+
* expected to follow up with setPendingReset(true) plus a full re-emit of
|
|
90
|
+
* live state, since the current session is now empty.
|
|
91
|
+
*/
|
|
92
|
+
moveCurrentSessionToLastSession(): Promise<void>;
|
|
93
|
+
/** Stops the save timer without flushing. */
|
|
94
|
+
dispose(): void;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* In-memory backend: no persistence beyond the object's lifetime. Useful for
|
|
99
|
+
* tests, server-side rendering, and as the reference implementation of the
|
|
100
|
+
* two-slot current/last contract.
|
|
101
|
+
*/
|
|
102
|
+
|
|
103
|
+
declare class InMemoryStorageBackend implements CommandStorageBackend {
|
|
104
|
+
private current_;
|
|
105
|
+
private last_;
|
|
106
|
+
appendCommands(commands: readonly SessionCommand[], truncate: boolean): void;
|
|
107
|
+
readLastSessionCommands(): ReadCommandsResult;
|
|
108
|
+
moveCurrentSessionToLastSession(): void;
|
|
109
|
+
/** Test hook: the commands persisted for the current session, if any. */
|
|
110
|
+
get currentSessionCommands(): readonly SessionCommand[] | null;
|
|
111
|
+
/** Test hook: the commands persisted for the last session, if any. */
|
|
112
|
+
get lastSessionCommands(): readonly SessionCommand[] | null;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* One session writer per profile. Ported from
|
|
117
|
+
* chromium-reference/chrome/browser/process_singleton.h.
|
|
118
|
+
*
|
|
119
|
+
* Chrome never lets two processes share a profile directory: ProcessSingleton
|
|
120
|
+
* is "named according to the user data directory, so we can be sure that no
|
|
121
|
+
* more than one copy of the application can be running at once with a given
|
|
122
|
+
* data directory" (h:45). A second launch gets PROCESS_NOTIFIED and stands
|
|
123
|
+
* down; only the PROCESS_NONE winner runs a SessionService over the profile.
|
|
124
|
+
*
|
|
125
|
+
* Two browser tabs of the same app are the web's version of two processes
|
|
126
|
+
* sharing a profile. The web cannot make the second tab exit, but it can make
|
|
127
|
+
* it stand down: the loser becomes a "secondary" SessionService with saving
|
|
128
|
+
* disabled (the SetSavingEnabled(false) state, session_service_base.cc:877)
|
|
129
|
+
* that neither rotates nor writes the shared log.
|
|
130
|
+
*
|
|
131
|
+
* The claim is made once, at startup, exactly like Chrome's — there is no
|
|
132
|
+
* mid-life takeover. When the owner dies its lock evaporates with the realm
|
|
133
|
+
* (the Web Lock analog of the OS reclaiming Chrome's SingletonLock), and the
|
|
134
|
+
* next realm to BOOT over that profile claims it and restores the session.
|
|
135
|
+
*/
|
|
136
|
+
/** 'owner' ~ PROCESS_NONE, 'secondary' ~ PROCESS_NOTIFIED (h:85). */
|
|
137
|
+
type ProcessSingletonResult = 'owner' | 'secondary';
|
|
138
|
+
interface ProcessSingleton {
|
|
139
|
+
/**
|
|
140
|
+
* Attempts to become the singleton for the profile. Resolves exactly once;
|
|
141
|
+
* repeated calls return the same promise. Mirrors
|
|
142
|
+
* NotifyOtherProcessOrCreate (h:119).
|
|
143
|
+
*/
|
|
144
|
+
acquire(): Promise<ProcessSingletonResult>;
|
|
145
|
+
/** Releases the claim if held. Mirrors Cleanup (h:133). Idempotent. */
|
|
146
|
+
release(): void;
|
|
147
|
+
}
|
|
148
|
+
interface WebLocksProcessSingletonOptions {
|
|
149
|
+
/** Lock name. One storage area (profile) = one name. */
|
|
150
|
+
name: string;
|
|
151
|
+
/** Injectable for tests / non-window realms. Defaults to navigator.locks. */
|
|
152
|
+
locks?: LockManager;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* ProcessSingleton over the Web Locks API. The owner holds an exclusive lock
|
|
156
|
+
* named for the profile until release() or realm death; contenders ask with
|
|
157
|
+
* ifAvailable and stand down instead of queueing, mirroring Chrome's
|
|
158
|
+
* startup-time claim.
|
|
159
|
+
*/
|
|
160
|
+
declare class WebLocksProcessSingleton implements ProcessSingleton {
|
|
161
|
+
private readonly name_;
|
|
162
|
+
private readonly locks_;
|
|
163
|
+
private acquirePromise_;
|
|
164
|
+
private releaseHold_;
|
|
165
|
+
private released_;
|
|
166
|
+
constructor(options: WebLocksProcessSingletonOptions);
|
|
167
|
+
acquire(): Promise<ProcessSingletonResult>;
|
|
168
|
+
/**
|
|
169
|
+
* Claim with bounded retries. Chrome's POSIX singleton retries its claim
|
|
170
|
+
* the same way — kRetryAttempts with timeout/retry_attempts sleeps
|
|
171
|
+
* (process_singleton_posix.cc:137-140, :794) — because a dying holder's
|
|
172
|
+
* lock disappears asynchronously. Web Lock releases also propagate
|
|
173
|
+
* asynchronously (the holder resolves its callback promise), so a realm
|
|
174
|
+
* booting right after another one released (HMR, dispose-then-reconstruct)
|
|
175
|
+
* needs a beat before the lock reads as free. A lock still held after the
|
|
176
|
+
* final attempt belongs to a live realm: stand down.
|
|
177
|
+
*/
|
|
178
|
+
private acquireWithRetries_;
|
|
179
|
+
private tryClaim_;
|
|
180
|
+
release(): void;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* The default wiring: Web Locks keyed by the backend's profile name when the
|
|
184
|
+
* platform has them, otherwise sole ownership (SSR, Node, older browsers —
|
|
185
|
+
* today's behavior).
|
|
186
|
+
*/
|
|
187
|
+
declare function createDefaultProcessSingleton(profileLockName: string | undefined): ProcessSingleton | null;
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Web Storage backend: persists the command log to localStorage (default) or
|
|
191
|
+
* sessionStorage. Both slots hold a JSON envelope `{version, commands}`; a
|
|
192
|
+
* write replaces the whole value, so unlike Chrome's incremental file we
|
|
193
|
+
* never need the trailing validity marker (command_storage_backend.cc writes
|
|
194
|
+
* kInitialStateMarkerCommandId to detect torn writes) — setItem is atomic.
|
|
195
|
+
*
|
|
196
|
+
* Synchronous on purpose: a pagehide flush only works reliably when the
|
|
197
|
+
* write completes before the handler returns.
|
|
198
|
+
*/
|
|
199
|
+
|
|
200
|
+
interface WebStorageBackendOptions {
|
|
201
|
+
/** Key prefix; slots live at `<key>/current` and `<key>/last`. */
|
|
202
|
+
key?: string;
|
|
203
|
+
/** Storage area to use. Defaults to window.localStorage. */
|
|
204
|
+
storage?: Storage;
|
|
205
|
+
}
|
|
206
|
+
declare class WebStorageBackend implements CommandStorageBackend {
|
|
207
|
+
/** Two realms over the same key contend for the same profile singleton. */
|
|
208
|
+
readonly profileLockName: string;
|
|
209
|
+
private readonly storage_;
|
|
210
|
+
private readonly currentKey_;
|
|
211
|
+
private readonly lastKey_;
|
|
212
|
+
/** Parsed mirror of the current slot, so appends don't re-parse. */
|
|
213
|
+
private currentCache_;
|
|
214
|
+
constructor(options?: WebStorageBackendOptions);
|
|
215
|
+
appendCommands(commands: readonly SessionCommand[], truncate: boolean): void;
|
|
216
|
+
readLastSessionCommands(): ReadCommandsResult;
|
|
217
|
+
moveCurrentSessionToLastSession(): void;
|
|
218
|
+
private readSlot_;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Turns a restored SessionWindow back into live tabs. Ported from
|
|
223
|
+
* chromium-reference/chrome/browser/sessions/session_restore.cc
|
|
224
|
+
* (SessionRestoreImpl::RestoreTabsToBrowser / RestoreTab).
|
|
225
|
+
*
|
|
226
|
+
* Restore order mirrors Chrome: tabs are created in visual order with their
|
|
227
|
+
* pinned state (AddRestoredTab), groups are formed and given their visual
|
|
228
|
+
* data afterwards (RestoreTabGroupMetadata), then the selected tab is
|
|
229
|
+
* activated. Group ids are re-generated by the model — exactly like Chrome,
|
|
230
|
+
* which relabels every restored group via TabGroupId::GenerateNew() to avoid
|
|
231
|
+
* cross-session id collisions — so callers get a groupIdMap back.
|
|
232
|
+
*/
|
|
233
|
+
|
|
234
|
+
interface RestoreOptions<T> {
|
|
235
|
+
/**
|
|
236
|
+
* Builds the live data payload for a restored tab. Defaults to the
|
|
237
|
+
* persisted `data` value as-is. Tabs persisted with navigation tracking
|
|
238
|
+
* only can derive their payload from currentNavigationEntry(tab).
|
|
239
|
+
*/
|
|
240
|
+
createTabData?: (tab: SessionTab) => T;
|
|
241
|
+
/**
|
|
242
|
+
* Keep the persisted tab ids (default). Ids already present in the model
|
|
243
|
+
* fall back to generated ones. Pass false to always generate fresh ids —
|
|
244
|
+
* Chrome's behavior, where restored tabs get new SessionIDs.
|
|
245
|
+
*/
|
|
246
|
+
preserveTabIds?: boolean;
|
|
247
|
+
/**
|
|
248
|
+
* Restore non-selected tabs in the discarded state, the analog of Chrome's
|
|
249
|
+
* deferred TabLoader (background tabs exist but don't load until first
|
|
250
|
+
* activation). Default false: everything restores loaded.
|
|
251
|
+
*/
|
|
252
|
+
deferLoading?: boolean;
|
|
253
|
+
}
|
|
254
|
+
interface RestoreResult {
|
|
255
|
+
tabsRestored: number;
|
|
256
|
+
/** Persisted tab id -> live tab id. Identity unless ids were regenerated. */
|
|
257
|
+
tabIdMap: Map<TabId, TabId>;
|
|
258
|
+
/** Persisted group id -> live group id (always regenerated by the model). */
|
|
259
|
+
groupIdMap: Map<TabGroupId, TabGroupId>;
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Appends a SessionWindow's tabs to `model`. The model is typically empty;
|
|
263
|
+
* with existing tabs the restored ones are appended after them (Chrome
|
|
264
|
+
* restores into an existing browser the same way, session_restore.cc's
|
|
265
|
+
* initial_tab_count handling).
|
|
266
|
+
*/
|
|
267
|
+
declare function restoreSessionWindow<T>(model: TabStripModel<T>, window: SessionWindow, options?: RestoreOptions<T>): RestoreResult;
|
|
268
|
+
|
|
269
|
+
/**
|
|
270
|
+
* SessionService: records TabStripModel mutations as a command log and reads
|
|
271
|
+
* the previous session back. Ported from
|
|
272
|
+
* chromium-reference/chrome/browser/sessions/session_service_base.cc and
|
|
273
|
+
* session_service.cc.
|
|
274
|
+
*
|
|
275
|
+
* In Chrome the service learns about tab changes through Browser /
|
|
276
|
+
* SessionTabHelper plumbing; here it is a TabStripModelObserver. Navigation
|
|
277
|
+
* events have no model-level source (tabs carry opaque `data`), so — exactly
|
|
278
|
+
* like SessionTabHelper driving SessionService — the embedding app reports
|
|
279
|
+
* them through navigateTab / updateTabNavigation / setSelectedNavigationIndex.
|
|
280
|
+
*
|
|
281
|
+
* Tab `data` is persisted automatically (kCommandSetTabData analog) on
|
|
282
|
+
* insert and on every data change, so apps that keep their url in `data`
|
|
283
|
+
* restore correctly with zero extra wiring.
|
|
284
|
+
*
|
|
285
|
+
* Deviation from Chrome: on inserts, moves, and removals we re-emit
|
|
286
|
+
* SetTabIndexInWindow for every tab whose index shifted, so the persisted
|
|
287
|
+
* visual order is always exact. Chrome tolerates stale indices and relies on
|
|
288
|
+
* periodic full rewrites; the in-buffer command swaps below keep our
|
|
289
|
+
* approach cheap.
|
|
290
|
+
*/
|
|
291
|
+
|
|
292
|
+
/** Commands between full log rewrites. Mirrors kWritesPerReset (session_service_base.cc:78). */
|
|
293
|
+
declare const WRITES_PER_RESET = 250;
|
|
294
|
+
/** Navigation entries persisted either side of the current one. Mirrors gMaxPersistNavigationCount. */
|
|
295
|
+
declare const MAX_PERSISTED_NAVIGATIONS = 6;
|
|
296
|
+
interface SessionServiceOptions<T> {
|
|
297
|
+
storage: CommandStorageBackend;
|
|
298
|
+
/**
|
|
299
|
+
* Converts tab data to a JSON-serializable value. Defaults to identity —
|
|
300
|
+
* fine when T is already plain JSON (e.g. `{ url: string }`).
|
|
301
|
+
*/
|
|
302
|
+
serializeTabData?: (data: T, tab: Tab<T>) => unknown;
|
|
303
|
+
/** Inverse of serializeTabData, used by restoreInto. Defaults to identity. */
|
|
304
|
+
deserializeTabData?: (raw: unknown) => T;
|
|
305
|
+
/** Delay before buffered commands hit storage. Default SAVE_DELAY_MS (2500). */
|
|
306
|
+
saveDelayMs?: number;
|
|
307
|
+
/** Commands between full rewrites. Default WRITES_PER_RESET (250). */
|
|
308
|
+
writesPerReset?: number;
|
|
309
|
+
/** Navigation entries kept either side of current. Default 6. */
|
|
310
|
+
maxPersistedNavigations?: number;
|
|
311
|
+
/**
|
|
312
|
+
* Flush synchronously on window `pagehide` (web teardown gives timers no
|
|
313
|
+
* chance to fire). Default true when a window exists. Only effective with
|
|
314
|
+
* a synchronous backend such as WebStorageBackend.
|
|
315
|
+
*/
|
|
316
|
+
flushOnPageHide?: boolean;
|
|
317
|
+
/** Observer-side failures are reported here instead of thrown. */
|
|
318
|
+
onError?: (error: unknown) => void;
|
|
319
|
+
/**
|
|
320
|
+
* Cross-realm coordination for the storage area — the ProcessSingleton
|
|
321
|
+
* port (process_singleton.h). Exactly one realm (browser tab) owns a
|
|
322
|
+
* profile; the rest become secondaries that neither rotate, write, nor
|
|
323
|
+
* restore it. Omit for the default: Web Locks keyed by
|
|
324
|
+
* storage.profileLockName when the platform has them, else sole ownership.
|
|
325
|
+
* Pass null to force sole ownership, or your own implementation for
|
|
326
|
+
* tests/custom environments.
|
|
327
|
+
*/
|
|
328
|
+
processSingleton?: ProcessSingleton | null;
|
|
329
|
+
}
|
|
330
|
+
interface AttachOptions {
|
|
331
|
+
/** Identifies this model in the log. Default DEFAULT_WINDOW_ID. */
|
|
332
|
+
windowId?: SessionWindowId;
|
|
333
|
+
}
|
|
334
|
+
interface RestoreIntoOptions<T> extends RestoreOptions<T> {
|
|
335
|
+
/** Restore (and attach as) this window. Defaults to the first saved window. */
|
|
336
|
+
windowId?: SessionWindowId;
|
|
337
|
+
}
|
|
338
|
+
interface RestoreIntoResult extends RestoreResult {
|
|
339
|
+
/** False when there was no saved window to restore (e.g. first run). */
|
|
340
|
+
restored: boolean;
|
|
341
|
+
/** The full snapshot, for callers that also restore other windows. */
|
|
342
|
+
snapshot: SessionSnapshot;
|
|
343
|
+
/**
|
|
344
|
+
* 'owner' when this realm persists the session; 'secondary' when another
|
|
345
|
+
* realm already owns the storage area — this service then restored nothing
|
|
346
|
+
* and will record nothing.
|
|
347
|
+
*/
|
|
348
|
+
ownership: ProcessSingletonResult;
|
|
349
|
+
}
|
|
350
|
+
declare class SessionService<T = unknown> {
|
|
351
|
+
private readonly storage_;
|
|
352
|
+
private readonly manager_;
|
|
353
|
+
private readonly serializeTabData_;
|
|
354
|
+
private readonly deserializeTabData_;
|
|
355
|
+
private readonly writesPerReset_;
|
|
356
|
+
private readonly maxPersistedNavigations_;
|
|
357
|
+
private readonly onError_;
|
|
358
|
+
/**
|
|
359
|
+
* Resolves once the profile claim is settled and, for the owner, the
|
|
360
|
+
* previous session has been rotated to the last slot.
|
|
361
|
+
*/
|
|
362
|
+
private readonly ready_;
|
|
363
|
+
private readonly windows_;
|
|
364
|
+
private readonly navState_;
|
|
365
|
+
private readonly tabExtraData_;
|
|
366
|
+
private readonly windowExtraData_;
|
|
367
|
+
private activeWindowId_;
|
|
368
|
+
/** Mirrors rebuild_on_next_save_ (session_service_base.cc). */
|
|
369
|
+
private rebuildOnNextSave_;
|
|
370
|
+
private pageHideListener_;
|
|
371
|
+
private disposed_;
|
|
372
|
+
private readonly singleton_;
|
|
373
|
+
private ownership_;
|
|
374
|
+
/** Mirrors is_saving_enabled_ (session_service_base.h:337). */
|
|
375
|
+
private savingEnabled_;
|
|
376
|
+
constructor(options: SessionServiceOptions<T>);
|
|
377
|
+
/**
|
|
378
|
+
* Which side of the profile claim this service landed on: 'pending' until
|
|
379
|
+
* resolved, then 'owner' (this realm persists the session) or 'secondary'
|
|
380
|
+
* (another realm owns the storage area; this service records and restores
|
|
381
|
+
* nothing). Settled by the time getLastSession/restoreInto resolve.
|
|
382
|
+
*/
|
|
383
|
+
get ownership(): 'pending' | ProcessSingletonResult;
|
|
384
|
+
/** Starts rotation; returns the pending promise when async, else null. */
|
|
385
|
+
private rotateNow_;
|
|
386
|
+
/** Port of SetSavingEnabled (session_service_base.cc:877). */
|
|
387
|
+
private setSavingEnabled_;
|
|
388
|
+
/**
|
|
389
|
+
* Starts recording a model under the given window id and schedules a full
|
|
390
|
+
* snapshot of its current state (the SetSavingEnabled(true) startup path,
|
|
391
|
+
* session_service_base.cc:412). Returns a detach function.
|
|
392
|
+
*/
|
|
393
|
+
attach(model: TabStripModel<T>, options?: AttachOptions): () => void;
|
|
394
|
+
/**
|
|
395
|
+
* Stops recording a window. The window's commands stay in the log until
|
|
396
|
+
* the next full rewrite; use markWindowClosed first to drop it eagerly.
|
|
397
|
+
*/
|
|
398
|
+
detach(windowId: SessionWindowId): void;
|
|
399
|
+
/**
|
|
400
|
+
* Records the window as closed and detaches it. Tab closes are committed
|
|
401
|
+
* alongside kCommandWindowClosed, mirroring CommitPendingCloses
|
|
402
|
+
* (session_service.cc) — otherwise the tabs' surviving commands would
|
|
403
|
+
* resurrect the window husk during rebuild.
|
|
404
|
+
*/
|
|
405
|
+
markWindowClosed(windowId: SessionWindowId): void;
|
|
406
|
+
/** Records which window is active (kCommandSetActiveWindow). */
|
|
407
|
+
setActiveWindow(windowId: SessionWindowId): void;
|
|
408
|
+
/**
|
|
409
|
+
* Records that a tab committed a new navigation: forward history is pruned
|
|
410
|
+
* and the new entry becomes current — normal browser semantics. Untracked
|
|
411
|
+
* tab ids are ignored, like commands for untracked windows in Chrome.
|
|
412
|
+
*/
|
|
413
|
+
navigateTab(tabId: TabId, entry: {
|
|
414
|
+
url: string;
|
|
415
|
+
title?: string;
|
|
416
|
+
state?: unknown;
|
|
417
|
+
timestamp?: number;
|
|
418
|
+
}): void;
|
|
419
|
+
/**
|
|
420
|
+
* Replaces-or-inserts one navigation entry by its index — e.g. the current
|
|
421
|
+
* page's title or scroll state changed in place. Mirrors
|
|
422
|
+
* UpdateTabNavigation (session_service.cc).
|
|
423
|
+
*/
|
|
424
|
+
updateTabNavigation(tabId: TabId, navigation: SerializedNavigationEntry): void;
|
|
425
|
+
/** Records back/forward movement. Mirrors SetSelectedNavigationIndex. */
|
|
426
|
+
setSelectedNavigationIndex(tabId: TabId, index: number): void;
|
|
427
|
+
/** Removes `count` entries from index value `index`. Mirrors TabNavigationPathPruned. */
|
|
428
|
+
pruneTabNavigations(tabId: TabId, index: number, count: number): void;
|
|
429
|
+
setTabExtraData(tabId: TabId, key: string, value: string): void;
|
|
430
|
+
setWindowExtraData(windowId: SessionWindowId, key: string, value: string): void;
|
|
431
|
+
/** Replays the previous session's log. Mirrors GetLastSession. */
|
|
432
|
+
getLastSession(): Promise<SessionSnapshot>;
|
|
433
|
+
/**
|
|
434
|
+
* The one-call integration: restores the previous session's window into
|
|
435
|
+
* `model` (when there is one) and attaches the model so the new session is
|
|
436
|
+
* recorded. Restored navigation histories and extra data are re-adopted so
|
|
437
|
+
* they survive future log rewrites.
|
|
438
|
+
*/
|
|
439
|
+
restoreInto(model: TabStripModel<T>, options?: RestoreIntoOptions<T>): Promise<RestoreIntoResult>;
|
|
440
|
+
/** Flushes buffered commands now (e.g. before an intentional teardown). */
|
|
441
|
+
saveNow(): Promise<void>;
|
|
442
|
+
/** True while commands are buffered awaiting the save timer. */
|
|
443
|
+
get hasPendingSave(): boolean;
|
|
444
|
+
/**
|
|
445
|
+
* Discards the log and rewrites it from live state. Mirrors
|
|
446
|
+
* ScheduleResetCommands (session_service_base.cc:404) +
|
|
447
|
+
* BuildCommandsFromBrowsers (cc:767).
|
|
448
|
+
*/
|
|
449
|
+
scheduleResetCommands(): void;
|
|
450
|
+
/** Detaches everything and stops timers. Does not flush — saveNow() first if needed. */
|
|
451
|
+
dispose(): void;
|
|
452
|
+
private checkNotDisposed_;
|
|
453
|
+
private findTab_;
|
|
454
|
+
/** Replace-or-insert by navigation index (session_service_commands.cc:664). */
|
|
455
|
+
private insertNavigation_;
|
|
456
|
+
private serializeTab_;
|
|
457
|
+
/**
|
|
458
|
+
* Coalesces a new command with a buffered one when only the latest value
|
|
459
|
+
* matters. Port of ReplacePendingCommand (session_service_commands.cc:1344)
|
|
460
|
+
* — Chrome only handles UpdateTabNavigation and SetActiveWindow; the other
|
|
461
|
+
* last-write-wins commands here are this port's extension, safe because the
|
|
462
|
+
* rebuild treats each of them as a keyed assignment.
|
|
463
|
+
*/
|
|
464
|
+
private replacePendingCommand_;
|
|
465
|
+
/** Mirrors SessionServiceBase::ScheduleCommand (session_service_base.cc:788). */
|
|
466
|
+
private scheduleCommand_;
|
|
467
|
+
/** SetTabIndexInWindow for every tab in [lo, hi] — see the header comment. */
|
|
468
|
+
private emitIndexRange_;
|
|
469
|
+
/** Dedup-cached SetSelectedTabInWindow, like session_service.cc. */
|
|
470
|
+
private maybeEmitSelectedTab_;
|
|
471
|
+
/**
|
|
472
|
+
* BuildCommandsForBrowser + BuildCommandsForTab
|
|
473
|
+
* (session_service_base.cc:672, :592), adapted to one TabStripModel.
|
|
474
|
+
*/
|
|
475
|
+
private buildCommandsForWindow_;
|
|
476
|
+
private createObserver_;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
export { type AttachOptions, CommandStorageBackend, CommandStorageManager, type CommandStorageManagerDelegate, type CommandStorageManagerOptions, InMemoryStorageBackend, MAX_PERSISTED_NAVIGATIONS, type ProcessSingleton, type ProcessSingletonResult, ReadCommandsResult, type RestoreIntoOptions, type RestoreIntoResult, type RestoreOptions, type RestoreResult, SAVE_DELAY_MS, SerializedNavigationEntry, SessionCommand, SessionService, type SessionServiceOptions, SessionSnapshot, SessionTab, SessionWindow, SessionWindowId, WRITES_PER_RESET, WebLocksProcessSingleton, type WebLocksProcessSingletonOptions, WebStorageBackend, type WebStorageBackendOptions, createDefaultProcessSingleton, restoreSessionWindow };
|