selfstore 1.8.16 → 1.8.17

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/flows.d.ts CHANGED
@@ -1,11 +1,11 @@
1
- import { b as ConnectKind, S as StoreLike, C as ConnectTargets } from './connect-DaZFPJdt.js';
2
- export { c as ConnectFlow, a as ConnectFlowOptions, d as ConnectFlowOutcome, e as ConnectResolution, f as ConnectSnapshot, g as ConnectStep, h as Connector, F as FlowHost, R as ResumeOffer, i as connectFlow } from './connect-DaZFPJdt.js';
3
- import { S as StoreError, k as ReplicaState, B as BackupTarget } from './store-CiLoRJmy.js';
1
+ import { b as ConnectKind, S as StoreLike, C as ConnectTargets } from './connect-BaWYvB1w.js';
2
+ export { c as ConnectFlow, a as ConnectFlowOptions, d as ConnectFlowOutcome, e as ConnectResolution, f as ConnectSnapshot, g as ConnectStep, h as Connector, F as FlowHost, R as ResumeOffer, i as connectFlow } from './connect-BaWYvB1w.js';
3
+ import { S as StoreError, k as ReplicaState, B as BackupTarget } from './store-CCe8b5Eg.js';
4
4
  import { F as FlowStore } from './machine-ALMkT3mk.js';
5
5
  export { w as withDeadline } from './machine-ALMkT3mk.js';
6
- import { W as WebdavConfig, S as S3Config } from './s3-DgyTwMRc.js';
6
+ import { W as WebdavConfig, S as S3Config } from './s3-CCE6lc_U.js';
7
7
  import './cache-ilsK3Tki.js';
8
- import './drive-B2fm71qD.js';
8
+ import './drive-BUPsPaIu.js';
9
9
  import './sync.js';
10
10
 
11
11
  /** The one replica this flow manages, as its id on the engine. */
@@ -1,4 +1,4 @@
1
- import { B as BackupTarget, P as PeerSource, L as LocalStore } from './store-CiLoRJmy.js';
1
+ import { B as BackupTarget, P as PeerSource, L as LocalStore } from './store-CCe8b5Eg.js';
2
2
  import { K as KV } from './cache-ilsK3Tki.js';
3
3
  import './sync.js';
4
4
 
package/dist/index.d.ts CHANGED
@@ -1,12 +1,12 @@
1
- import { o as Snapshot, E as EncodeOptions, H as Header, f as PasswordPolicy, B as BackupTarget, r as StatusDescriptor, S as StoreError, c as LocalStoreState, L as LocalStore } from './store-CiLoRJmy.js';
2
- export { d as Mode, e as PasswordCheck, g as PasswordRequirement, l as SelfstoreError, m as SelfstoreErrorCode, n as Severity, p as SnapshotFile, q as StatusAction, t as StorageState, T as TargetKind, x as checkPasswordPolicy, C as errorLabelKey, G as isSelfstoreError } from './store-CiLoRJmy.js';
1
+ import { o as Snapshot, E as EncodeOptions, H as Header, f as PasswordPolicy, B as BackupTarget, r as StatusDescriptor, S as StoreError, c as LocalStoreState, L as LocalStore } from './store-CCe8b5Eg.js';
2
+ export { d as Mode, e as PasswordCheck, g as PasswordRequirement, l as SelfstoreError, m as SelfstoreErrorCode, n as Severity, p as SnapshotFile, q as StatusAction, t as StorageState, T as TargetKind, x as checkPasswordPolicy, C as errorLabelKey, G as isSelfstoreError } from './store-CCe8b5Eg.js';
3
3
  import { L as LocalCache, K as KV } from './cache-ilsK3Tki.js';
4
4
  import { SyncConfig } from './sync.js';
5
- import { R as ResumeOffer, C as ConnectTargets } from './connect-DaZFPJdt.js';
6
- import { f as BackupsManager } from './manager-BqzTVaep.js';
7
- import { a as DriveAuth } from './drive-B2fm71qD.js';
8
- import { W as WebdavConfig, S as S3Config } from './s3-DgyTwMRc.js';
9
- export { f as changePassword, g as gisDriveAuth, p as pickFromDisk, s as saveToDisk } from './local-CldSa9EY.js';
5
+ import { R as ResumeOffer, C as ConnectTargets } from './connect-BaWYvB1w.js';
6
+ import { f as BackupsManager } from './manager-CaMd6T1T.js';
7
+ import { a as DriveAuth } from './drive-BUPsPaIu.js';
8
+ import { W as WebdavConfig, S as S3Config } from './s3-CCE6lc_U.js';
9
+ export { f as changePassword, g as gisDriveAuth, p as pickFromDisk, s as saveToDisk } from './local-Dt1hYNG4.js';
10
10
  import './machine-ALMkT3mk.js';
11
11
 
12
12
  declare const BACKUP_EXTENSION = ".zip";
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { indexedDbCache, memoryCache, gisDriveAuth, isLockableCache, createLocalStore } from './chunk-TXAMWBG5.js';
2
- export { gisDriveAuth } from './chunk-TXAMWBG5.js';
1
+ import { indexedDbCache, memoryCache, gisDriveAuth, isLockableCache, createLocalStore } from './chunk-3BPGPSPX.js';
2
+ export { gisDriveAuth } from './chunk-3BPGPSPX.js';
3
3
  import './chunk-SKWHKM25.js';
4
4
  import { saveToDisk } from './chunk-DCEXWSM6.js';
5
5
  export { pickFromDisk, saveToDisk } from './chunk-DCEXWSM6.js';
@@ -1,5 +1,5 @@
1
- import { o as Snapshot, E as EncodeOptions, H as Header } from './store-CiLoRJmy.js';
2
- import { a as DriveAuth } from './drive-B2fm71qD.js';
1
+ import { o as Snapshot, E as EncodeOptions, H as Header } from './store-CCe8b5Eg.js';
2
+ import { a as DriveAuth } from './drive-BUPsPaIu.js';
3
3
 
4
4
  /** Serialize a snapshot to a portable backup blob (compressed; encrypted if a password is given). */
5
5
  declare function exportSnapshot(snapshot: Snapshot, opts: EncodeOptions): Promise<Blob>;
@@ -1,5 +1,5 @@
1
1
  import { K as KV } from './cache-ilsK3Tki.js';
2
- import { B as BackupTarget, L as LocalStore } from './store-CiLoRJmy.js';
2
+ import { B as BackupTarget, L as LocalStore } from './store-CCe8b5Eg.js';
3
3
  import { F as FlowStore } from './machine-ALMkT3mk.js';
4
4
 
5
5
  /** What the destination reports about a listed file (one cheap metadata call). */
@@ -1,4 +1,4 @@
1
- import { B as BackupTarget, P as PeerSource } from './store-CiLoRJmy.js';
1
+ import { B as BackupTarget, P as PeerSource } from './store-CCe8b5Eg.js';
2
2
  import { K as KV } from './cache-ilsK3Tki.js';
3
3
 
4
4
  /**
@@ -359,6 +359,24 @@ interface LocalStoreState {
359
359
  locked: boolean;
360
360
  saving: boolean;
361
361
  lastSavedAt: number | null;
362
+ /**
363
+ * When a PORTABLE COPY was last written (an export the user asked for), or
364
+ * null if never. Distinct from `lastSavedAt`, which is the durable
365
+ * destination: a copy is a snapshot that leaves, a destination is kept up to
366
+ * date.
367
+ */
368
+ lastCopyAt: number | null;
369
+ /**
370
+ * Entries have been recorded since that copy was written.
371
+ *
372
+ * The store knew this only in its download-only mode, where the copy IS the
373
+ * save. Everywhere else nobody followed it, so an app that let its user
374
+ * export could say nothing about a copy going stale - and one of them found
375
+ * out the hard way that a copy written in the morning was still announced as
376
+ * up to date in the evening. False while no copy was ever written: there is
377
+ * nothing to be stale.
378
+ */
379
+ copyIsStale: boolean;
362
380
  status: StatusDescriptor;
363
381
  /** The last durable-target problem (upload/refresh), or null. */
364
382
  lastError: StoreError | null;
package/dist/widgets.d.ts CHANGED
@@ -1,11 +1,11 @@
1
- import { S as StoreLike, F as FlowHost, C as ConnectTargets, a as ConnectFlowOptions, b as ConnectKind, c as ConnectFlow } from './connect-DaZFPJdt.js';
1
+ import { S as StoreLike, F as FlowHost, C as ConnectTargets, a as ConnectFlowOptions, b as ConnectKind, c as ConnectFlow } from './connect-BaWYvB1w.js';
2
2
  import { ShareEngine, ShareLevel, ShareFlow, JoinEngine, JoinFlow, ReplicaFlow } from './flows.js';
3
- import { f as BackupsManager } from './manager-BqzTVaep.js';
4
- import './store-CiLoRJmy.js';
3
+ import { f as BackupsManager } from './manager-CaMd6T1T.js';
4
+ import './store-CCe8b5Eg.js';
5
5
  import './cache-ilsK3Tki.js';
6
6
  import './sync.js';
7
- import './drive-B2fm71qD.js';
8
- import './s3-DgyTwMRc.js';
7
+ import './drive-BUPsPaIu.js';
8
+ import './s3-CCE6lc_U.js';
9
9
  import './machine-ALMkT3mk.js';
10
10
 
11
11
  /** Flat key -> string map; widgets merge a partial override over EN defaults. */
@@ -746,6 +746,7 @@ declare class SelfstoreStorageElement extends FlowWidget {
746
746
 
747
747
  declare class SelfstoreAccountElement extends FlowWidget {
748
748
  #private;
749
+ static get observedAttributes(): string[];
749
750
  protected defaults(): WidgetLabels;
750
751
  protected packs(): Record<string, WidgetLabels>;
751
752
  constructor();
@@ -755,10 +756,23 @@ declare class SelfstoreAccountElement extends FlowWidget {
755
756
  * the user picks one. Returns false (or throws) to stop. */
756
757
  get confirmAction(): ((a: DestinationAction) => boolean | Promise<boolean>) | null;
757
758
  set confirmAction(fn: ((a: DestinationAction) => boolean | Promise<boolean>) | null);
759
+ /**
760
+ * What the trigger says: the DESTINATION it goes to (default), or the STATE
761
+ * it is in.
762
+ *
763
+ * Naming the place is right when there is a choice - it makes local-first
764
+ * visible without opening anything. It says nothing at all when an app
765
+ * offers exactly one destination: "a file" where a file is the only thing it
766
+ * could ever be. Such an app states a condition instead - saved, unsaved,
767
+ * locked - which is the part that changes.
768
+ */
769
+ get trigger(): 'destination' | 'status';
770
+ set trigger(v: 'destination' | 'status' | null);
758
771
  /** Whether the menu is on screen. Settable, so a host can close it from its
759
772
  * own router after the settings item navigated away. */
760
773
  get open(): boolean;
761
774
  set open(v: boolean);
775
+ attributeChangedCallback(name: string): void;
762
776
  connectedCallback(): void;
763
777
  disconnectedCallback(): void;
764
778
  /** While the menu is open: a clock for the relative time, and the two ways
@@ -791,6 +805,13 @@ declare class SelfstoreAccountElement extends FlowWidget {
791
805
  /** Change backup: detach, and let the first-run screen take it from there.
792
806
  * The data stays; only the destination is let go. */
793
807
  private change;
808
+ /**
809
+ * What the trigger reads. The destination by default; the state when an app
810
+ * has only one destination to offer, where naming it says nothing that ever
811
+ * changes. The state comes from <selfstore-status>'s own words, so the two
812
+ * surfaces cannot drift.
813
+ */
814
+ private said;
794
815
  private card;
795
816
  protected view(into: HTMLElement): void;
796
817
  /**
package/dist/widgets.js CHANGED
@@ -2155,8 +2155,13 @@ var SelfstoreStatusElement = class extends FlowWidget {
2155
2155
  const copie = this.t(jumelle);
2156
2156
  return copie === jumelle ? this.t(cle) : copie;
2157
2157
  };
2158
+ const selonLeType = (cle) => {
2159
+ const jumelle = `${cle}.${targetKind}`;
2160
+ const copie = this.t(jumelle, { label: label ?? "" });
2161
+ return copie === jumelle ? null : copie;
2162
+ };
2158
2163
  const { lastSavedAt } = host.engine.state;
2159
- const text = label ? this.t(status.labelKey, { label }) : sansLieu(status.labelKey);
2164
+ const text = selonLeType(status.labelKey) ?? (label ? this.t(status.labelKey, { label }) : sansLieu(status.labelKey));
2160
2165
  const dot = h("span", {
2161
2166
  part: `status-dot sev-${status.severity}`,
2162
2167
  "aria-hidden": "true"
@@ -2214,7 +2219,7 @@ var SelfstoreStatusElement = class extends FlowWidget {
2214
2219
  const place = where !== `status.where.${targetKind}` ? where : own ?? named ?? label ?? "";
2215
2220
  const when = lastSavedAt ? this.since(lastSavedAt, this.t("status.justNow")) : "";
2216
2221
  const sub = [place, status.state === "saved" ? when : ""].filter(Boolean).join(", ");
2217
- const title = sub ? sansLieu(status.labelKey) : text;
2222
+ const title = selonLeType(status.labelKey) ?? (sub ? sansLieu(status.labelKey) : text);
2218
2223
  put(
2219
2224
  into,
2220
2225
  h(
@@ -4123,6 +4128,9 @@ var ACCOUNT_STYLES = `
4123
4128
  of ZERO - the pill collapsed to its dot in a flex header, with the label
4124
4129
  overflowing off screen. Nothing here queries its own width. */
4125
4130
  [part~='stack'] { container-type: normal; display: block; }
4131
+ /* A state in the trigger is a line already: no dot of its own, no action - the
4132
+ press opens the menu, where the gesture lives. */
4133
+ [part~='account-trigger-status'] [part~='status-action'] { display: none; }
4126
4134
  [part~='account-trigger'] {
4127
4135
  display: inline-flex;
4128
4136
  align-items: center;
@@ -4228,7 +4236,11 @@ var ACCOUNT_STYLES = `
4228
4236
  `;
4229
4237
  var TICK_MS = 3e4;
4230
4238
  var SelfstoreAccountElement = class extends FlowWidget {
4239
+ static get observedAttributes() {
4240
+ return ["trigger"];
4241
+ }
4231
4242
  #confirm = null;
4243
+ #trigger = "destination";
4232
4244
  #open = false;
4233
4245
  #error = null;
4234
4246
  #timer = null;
@@ -4261,6 +4273,23 @@ var SelfstoreAccountElement = class extends FlowWidget {
4261
4273
  set confirmAction(fn) {
4262
4274
  this.#confirm = fn;
4263
4275
  }
4276
+ /**
4277
+ * What the trigger says: the DESTINATION it goes to (default), or the STATE
4278
+ * it is in.
4279
+ *
4280
+ * Naming the place is right when there is a choice - it makes local-first
4281
+ * visible without opening anything. It says nothing at all when an app
4282
+ * offers exactly one destination: "a file" where a file is the only thing it
4283
+ * could ever be. Such an app states a condition instead - saved, unsaved,
4284
+ * locked - which is the part that changes.
4285
+ */
4286
+ get trigger() {
4287
+ return this.#trigger;
4288
+ }
4289
+ set trigger(v) {
4290
+ this.#trigger = v === "status" ? "status" : "destination";
4291
+ this.rerender();
4292
+ }
4264
4293
  /** Whether the menu is on screen. Settable, so a host can close it from its
4265
4294
  * own router after the settings item navigated away. */
4266
4295
  get open() {
@@ -4272,8 +4301,16 @@ var SelfstoreAccountElement = class extends FlowWidget {
4272
4301
  this.watch();
4273
4302
  this.rerender();
4274
4303
  }
4304
+ attributeChangedCallback(name) {
4305
+ if (name === "trigger") {
4306
+ const value = this.attr(name);
4307
+ if (value !== null) this.trigger = value;
4308
+ }
4309
+ }
4275
4310
  connectedCallback() {
4276
4311
  super.connectedCallback();
4312
+ const trigger = this.attr("trigger");
4313
+ if (trigger !== null) this.trigger = trigger;
4277
4314
  this.follow(this.hostOf());
4278
4315
  }
4279
4316
  disconnectedCallback() {
@@ -4375,6 +4412,23 @@ var SelfstoreAccountElement = class extends FlowWidget {
4375
4412
  this.rerender();
4376
4413
  }
4377
4414
  }
4415
+ /**
4416
+ * What the trigger reads. The destination by default; the state when an app
4417
+ * has only one destination to offer, where naming it says nothing that ever
4418
+ * changes. The state comes from <selfstore-status>'s own words, so the two
4419
+ * surfaces cannot drift.
4420
+ */
4421
+ said(host) {
4422
+ if (this.#trigger !== "status") return this.named(host);
4423
+ const el = document.createElement(
4424
+ siblingTag(this.localName, "account", "status")
4425
+ );
4426
+ el.setAttribute("variant", "line");
4427
+ el.setAttribute("part", "account-trigger-status");
4428
+ el.labels = this.labels;
4429
+ el.store = this.store;
4430
+ return el;
4431
+ }
4378
4432
  card(host) {
4379
4433
  const { targetKind } = host.engine.state;
4380
4434
  const icon = this.icons[targetKind];
@@ -4415,7 +4469,7 @@ var SelfstoreAccountElement = class extends FlowWidget {
4415
4469
  // The severity colors the DOT, never the label: a whole line turning
4416
4470
  // amber reads as a warning about the destination's name.
4417
4471
  h("span", { part: `account-dot sev-${status.severity}` }),
4418
- h("span", {}, this.named(host))
4472
+ h("span", { part: "account-trigger-text" }, this.said(host))
4419
4473
  );
4420
4474
  const menu = this.#open ? h(
4421
4475
  "div",