@flrande/bak-extension 0.3.2 → 0.3.4
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/dist/.bak-e2e-build-stamp +1 -1
- package/dist/background.global.js +23 -7
- package/package.json +2 -2
- package/src/workspace.ts +26 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
2026-03-
|
|
1
|
+
2026-03-09T06:27:35.243Z
|
|
@@ -169,10 +169,12 @@
|
|
|
169
169
|
};
|
|
170
170
|
}
|
|
171
171
|
async openTab(options = {}) {
|
|
172
|
+
const workspaceId = this.normalizeWorkspaceId(options.workspaceId);
|
|
173
|
+
const hadWorkspace = await this.loadWorkspaceRecord(workspaceId) !== null;
|
|
172
174
|
const ensured = await this.ensureWorkspace({
|
|
173
|
-
workspaceId
|
|
175
|
+
workspaceId,
|
|
174
176
|
focus: false,
|
|
175
|
-
initialUrl: options.url ?? DEFAULT_WORKSPACE_URL
|
|
177
|
+
initialUrl: hadWorkspace ? options.url ?? DEFAULT_WORKSPACE_URL : DEFAULT_WORKSPACE_URL
|
|
176
178
|
});
|
|
177
179
|
let state = { ...ensured.workspace, tabIds: [...ensured.workspace.tabIds], tabs: [...ensured.workspace.tabs] };
|
|
178
180
|
if (state.windowId !== null && state.tabs.length === 0) {
|
|
@@ -204,7 +206,7 @@
|
|
|
204
206
|
throw error;
|
|
205
207
|
}
|
|
206
208
|
const repaired = await this.ensureWorkspace({
|
|
207
|
-
workspaceId
|
|
209
|
+
workspaceId,
|
|
208
210
|
focus: false,
|
|
209
211
|
initialUrl: desiredUrl
|
|
210
212
|
});
|
|
@@ -328,13 +330,13 @@
|
|
|
328
330
|
await this.storage.save(null);
|
|
329
331
|
return { ok: true };
|
|
330
332
|
}
|
|
333
|
+
await this.storage.save(null);
|
|
331
334
|
if (state.windowId !== null) {
|
|
332
335
|
const existingWindow = await this.browser.getWindow(state.windowId);
|
|
333
336
|
if (existingWindow) {
|
|
334
337
|
await this.browser.closeWindow(state.windowId);
|
|
335
338
|
}
|
|
336
339
|
}
|
|
337
|
-
await this.storage.save(null);
|
|
338
340
|
return { ok: true };
|
|
339
341
|
}
|
|
340
342
|
async resolveTarget(options = {}) {
|
|
@@ -597,17 +599,31 @@
|
|
|
597
599
|
};
|
|
598
600
|
}
|
|
599
601
|
async resolveReusablePrimaryTab(workspace, allowReuse) {
|
|
600
|
-
if (
|
|
602
|
+
if (workspace.windowId === null) {
|
|
601
603
|
return null;
|
|
602
604
|
}
|
|
603
605
|
if (workspace.primaryTabId !== null) {
|
|
604
606
|
const trackedPrimary = workspace.tabs.find((tab) => tab.id === workspace.primaryTabId) ?? await this.waitForTrackedTab(workspace.primaryTabId, workspace.windowId);
|
|
605
|
-
if (trackedPrimary) {
|
|
607
|
+
if (trackedPrimary && (allowReuse || this.isReusableBlankWorkspaceTab(trackedPrimary, workspace))) {
|
|
606
608
|
return trackedPrimary;
|
|
607
609
|
}
|
|
608
610
|
}
|
|
609
611
|
const windowTabs = await this.waitForWindowTabs(workspace.windowId, 750);
|
|
610
|
-
|
|
612
|
+
if (windowTabs.length !== 1) {
|
|
613
|
+
return null;
|
|
614
|
+
}
|
|
615
|
+
const candidate = windowTabs[0];
|
|
616
|
+
if (allowReuse || this.isReusableBlankWorkspaceTab(candidate, workspace)) {
|
|
617
|
+
return candidate;
|
|
618
|
+
}
|
|
619
|
+
return null;
|
|
620
|
+
}
|
|
621
|
+
isReusableBlankWorkspaceTab(tab, workspace) {
|
|
622
|
+
if (workspace.tabIds.length > 1) {
|
|
623
|
+
return false;
|
|
624
|
+
}
|
|
625
|
+
const normalizedUrl = tab.url.trim().toLowerCase();
|
|
626
|
+
return normalizedUrl === "" || normalizedUrl === DEFAULT_WORKSPACE_URL;
|
|
611
627
|
}
|
|
612
628
|
async waitForWindow(windowId, timeoutMs = 750) {
|
|
613
629
|
const deadline = Date.now() + timeoutMs;
|
package/package.json
CHANGED
package/src/workspace.ts
CHANGED
|
@@ -247,10 +247,12 @@ export class WorkspaceManager {
|
|
|
247
247
|
}
|
|
248
248
|
|
|
249
249
|
async openTab(options: WorkspaceOpenTabOptions = {}): Promise<{ workspace: WorkspaceInfo; tab: WorkspaceTab }> {
|
|
250
|
+
const workspaceId = this.normalizeWorkspaceId(options.workspaceId);
|
|
251
|
+
const hadWorkspace = (await this.loadWorkspaceRecord(workspaceId)) !== null;
|
|
250
252
|
const ensured = await this.ensureWorkspace({
|
|
251
|
-
workspaceId
|
|
253
|
+
workspaceId,
|
|
252
254
|
focus: false,
|
|
253
|
-
initialUrl: options.url ?? DEFAULT_WORKSPACE_URL
|
|
255
|
+
initialUrl: hadWorkspace ? options.url ?? DEFAULT_WORKSPACE_URL : DEFAULT_WORKSPACE_URL
|
|
254
256
|
});
|
|
255
257
|
let state = { ...ensured.workspace, tabIds: [...ensured.workspace.tabIds], tabs: [...ensured.workspace.tabs] };
|
|
256
258
|
if (state.windowId !== null && state.tabs.length === 0) {
|
|
@@ -285,7 +287,7 @@ export class WorkspaceManager {
|
|
|
285
287
|
throw error;
|
|
286
288
|
}
|
|
287
289
|
const repaired = await this.ensureWorkspace({
|
|
288
|
-
workspaceId
|
|
290
|
+
workspaceId,
|
|
289
291
|
focus: false,
|
|
290
292
|
initialUrl: desiredUrl
|
|
291
293
|
});
|
|
@@ -419,13 +421,15 @@ export class WorkspaceManager {
|
|
|
419
421
|
await this.storage.save(null);
|
|
420
422
|
return { ok: true };
|
|
421
423
|
}
|
|
424
|
+
// Clear persisted state before closing the window so tab/window removal
|
|
425
|
+
// listeners cannot race and resurrect an empty workspace record.
|
|
426
|
+
await this.storage.save(null);
|
|
422
427
|
if (state.windowId !== null) {
|
|
423
428
|
const existingWindow = await this.browser.getWindow(state.windowId);
|
|
424
429
|
if (existingWindow) {
|
|
425
430
|
await this.browser.closeWindow(state.windowId);
|
|
426
431
|
}
|
|
427
432
|
}
|
|
428
|
-
await this.storage.save(null);
|
|
429
433
|
return { ok: true };
|
|
430
434
|
}
|
|
431
435
|
|
|
@@ -728,17 +732,32 @@ export class WorkspaceManager {
|
|
|
728
732
|
}
|
|
729
733
|
|
|
730
734
|
private async resolveReusablePrimaryTab(workspace: WorkspaceInfo, allowReuse: boolean): Promise<WorkspaceTab | null> {
|
|
731
|
-
if (
|
|
735
|
+
if (workspace.windowId === null) {
|
|
732
736
|
return null;
|
|
733
737
|
}
|
|
734
738
|
if (workspace.primaryTabId !== null) {
|
|
735
739
|
const trackedPrimary = workspace.tabs.find((tab) => tab.id === workspace.primaryTabId) ?? (await this.waitForTrackedTab(workspace.primaryTabId, workspace.windowId));
|
|
736
|
-
if (trackedPrimary) {
|
|
740
|
+
if (trackedPrimary && (allowReuse || this.isReusableBlankWorkspaceTab(trackedPrimary, workspace))) {
|
|
737
741
|
return trackedPrimary;
|
|
738
742
|
}
|
|
739
743
|
}
|
|
740
744
|
const windowTabs = await this.waitForWindowTabs(workspace.windowId, 750);
|
|
741
|
-
|
|
745
|
+
if (windowTabs.length !== 1) {
|
|
746
|
+
return null;
|
|
747
|
+
}
|
|
748
|
+
const candidate = windowTabs[0]!;
|
|
749
|
+
if (allowReuse || this.isReusableBlankWorkspaceTab(candidate, workspace)) {
|
|
750
|
+
return candidate;
|
|
751
|
+
}
|
|
752
|
+
return null;
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
private isReusableBlankWorkspaceTab(tab: WorkspaceTab, workspace: WorkspaceInfo): boolean {
|
|
756
|
+
if (workspace.tabIds.length > 1) {
|
|
757
|
+
return false;
|
|
758
|
+
}
|
|
759
|
+
const normalizedUrl = tab.url.trim().toLowerCase();
|
|
760
|
+
return normalizedUrl === '' || normalizedUrl === DEFAULT_WORKSPACE_URL;
|
|
742
761
|
}
|
|
743
762
|
|
|
744
763
|
private async waitForWindow(windowId: number, timeoutMs = 750): Promise<WorkspaceWindow | null> {
|