dsh-mobile 0.3.1 → 0.3.2

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/lib/index.d.mts CHANGED
@@ -438,10 +438,16 @@ declare module '@deepseek-ai/cordis' {
438
438
  interface LocalExtensionManifest extends MobileExtensionManifest {}
439
439
  /** Public snapshot sent to the mobile browser. */
440
440
  interface MobileExtensionClientEntry extends MobileExtensionManifest {
441
+ readonly generation?: string;
441
442
  readonly scriptUrl?: string;
442
443
  readonly styleUrl?: string;
443
444
  readonly assetsUrl?: string;
444
445
  }
446
+ interface LocalAssetSnapshot {
447
+ readonly body: Buffer;
448
+ readonly digest: string;
449
+ readonly name: string;
450
+ }
445
451
  /** Small status summary used by the desktop mobile-access card. */
446
452
  interface MobileExtensionStatus {
447
453
  readonly loaded: number;
@@ -450,8 +456,9 @@ interface MobileExtensionStatus {
450
456
  interface ActiveLocalExtension {
451
457
  readonly manifest: LocalExtensionManifest;
452
458
  readonly directory: string;
453
- readonly scriptFile?: string;
454
- readonly styleFile?: string;
459
+ readonly scriptBody?: Buffer;
460
+ readonly styleBody?: Buffer;
461
+ readonly assets: ReadonlyMap<string, LocalAssetSnapshot>;
455
462
  readonly host: MobileExtensionDefinition;
456
463
  readonly controller: AbortController;
457
464
  readonly cleanups: readonly (() => void | Promise<void>)[];
@@ -465,42 +472,48 @@ declare function parseExtensionManifest(value: unknown): LocalExtensionManifest;
465
472
  declare class MobileAccessService extends Service {
466
473
  private readonly registered;
467
474
  private readonly local;
475
+ private readonly retired;
468
476
  private readonly failures;
477
+ private readonly contentListeners;
469
478
  private contentHash;
470
479
  private localRoot;
471
480
  private localContext;
472
481
  private localTimer;
473
482
  private localRefreshing;
483
+ private localRefreshAbort;
484
+ private localLifecycle;
474
485
  private localClosed;
475
486
  constructor(ctx: Context);
476
487
  /** Register a normal Cordis extension and return an idempotent disposer. */
477
488
  registerExtension(definition: MobileExtensionDefinition): () => void;
478
489
  /** Aggregate digest covering every registered and active local extension. */
479
490
  contentDigest(): string;
491
+ /** Subscribe to committed extension generation changes. */
492
+ onContentChanged(listener: () => void): () => void;
480
493
  private updateContentHash;
481
494
  /** Return the current client-facing manifest, deterministically sorted by id. */
482
495
  manifest(): readonly MobileExtensionClientEntry[];
483
496
  /** Return loaded and failed local extension counts without exposing host errors. */
484
497
  status(): MobileExtensionStatus;
485
498
  /** Locate one active extension. */
486
- extension(id: string): MobileExtensionDefinition | ActiveLocalExtension | undefined;
499
+ extension(id: string, generation?: string): MobileExtensionDefinition | ActiveLocalExtension | undefined;
487
500
  /** Return the active local generation signal for gateway cancellation wiring. */
488
- signal(id: string): AbortSignal | undefined;
501
+ signal(id: string, generation?: string): AbortSignal | undefined;
489
502
  /** Read a local client entry after validating that it remains inside its directory. */
490
- readClientFile(id: string, kind: 'script' | 'style', signal?: AbortSignal): Promise<{
503
+ readClientFile(id: string, kind: 'script' | 'style', signal?: AbortSignal, generation?: string): Promise<{
491
504
  readonly body: Buffer;
492
505
  readonly digest: string;
493
506
  }>;
494
- /** Read a local static asset after containment and size checks. */
495
- readAsset(id: string, assetPath: string, signal?: AbortSignal): Promise<{
507
+ /** Read a generation-pinned static asset from its validated snapshot. */
508
+ readAsset(id: string, assetPath: string, signal?: AbortSignal, generation?: string): Promise<{
496
509
  readonly body: Buffer;
497
510
  readonly digest: string;
498
511
  readonly name: string;
499
512
  }>;
500
513
  /** Invoke one action after parsing its input and binding the request lifetime. */
501
- invoke(id: string, actionName: string, input: unknown, context: MobileActionContext): Promise<unknown>;
514
+ invoke(id: string, actionName: string, input: unknown, context: MobileActionContext, generation?: string): Promise<unknown>;
502
515
  /** Match one route and invoke it with a generation-bound abort signal. */
503
- route(id: string, method: string, pathname: string, request: MobileRouteRequest): Promise<MobileRouteResponse>;
516
+ route(id: string, method: string, pathname: string, request: MobileRouteRequest, generation?: string): Promise<MobileRouteResponse>;
504
517
  /** Start the local directory watcher; an absent directory is intentionally inert. */
505
518
  startLocal(root: string, context: Context): Promise<void>;
506
519
  /** Stop the watcher and abort every local host generation. */
@@ -508,6 +521,7 @@ declare class MobileAccessService extends Service {
508
521
  /** Refresh all local extensions atomically; failures keep the previous snapshot. */
509
522
  refreshLocal(): Promise<void>;
510
523
  private stageAndCommit;
524
+ private retire;
511
525
  }
512
526
  /** Construct the service in a Cordis plugin without importing DSH internals. */
513
527
  declare function createMobileAccessService(ctx: Context): MobileAccessService;
@@ -534,6 +548,11 @@ declare class MobileAccessGateway {
534
548
  private readonly activeRequests;
535
549
  private readonly activeWebSockets;
536
550
  private readonly mobileBootBatches;
551
+ private readonly extensionEventListeners;
552
+ private extensionEventRevision;
553
+ private extensionChangeTimer;
554
+ private extensionChangeTask;
555
+ private legacyCustomDigest;
537
556
  private upstreamCookie;
538
557
  private upstreamCookieExpiresAt;
539
558
  private upstreamCookieTask;
@@ -543,6 +562,7 @@ declare class MobileAccessGateway {
543
562
  private started;
544
563
  private closeTask;
545
564
  private readonly removeSessionListener;
565
+ private readonly removeExtensionContentListener;
546
566
  private readonly renewLimiter;
547
567
  constructor(config: ResolvedGatewayConfig, store: DeviceStore, extensions?: MobileAccessService | undefined, upstreamAuthenticatedUrl?: string | undefined);
548
568
  /** Initialize durable state, validate TLS, and bind the externally reachable listener. */
@@ -580,6 +600,9 @@ declare class MobileAccessGateway {
580
600
  private allocateRequest;
581
601
  private proxyHttp;
582
602
  private abortSessionResources;
603
+ private broadcastExtensionChange;
604
+ private pollLegacyCustomChanges;
605
+ private openExtensionEventStream;
583
606
  private readUpgradeResponse;
584
607
  private handleUpgrade;
585
608
  /** Loopback-only DSH WebServer route for opening pairing and managing devices. */