@tak-ps/cloudtak 13.30.1 → 13.32.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.
@@ -121,6 +121,25 @@ export declare class PluginAPI {
121
121
  filter?: (feature: DBFeature) => boolean;
122
122
  }) => Observable<DBFeature[]>;
123
123
  };
124
+ /**
125
+ * Manage CoT Marti Queries
126
+ */
127
+ get cot(): {
128
+ /**
129
+ * Fetch the historic CoT points for a given UID from the TAK Server.
130
+ *
131
+ * Each point is returned as its own Feature retaining its temporal
132
+ * attributes so callers can build time-series visualizations.
133
+ *
134
+ * @param uid The CoT UID to fetch history for
135
+ * @param opts Optional time window constraints
136
+ */
137
+ history: (uid: string, opts?: {
138
+ start?: string;
139
+ end?: string;
140
+ secago?: number;
141
+ }) => Promise<DBFeature[]>;
142
+ };
124
143
  /**
125
144
  * Manage Breadcrumb Trails
126
145
  */
@@ -0,0 +1,9 @@
1
+ export declare class TimeoutError extends Error {
2
+ constructor(message: string);
3
+ }
4
+ /**
5
+ * Bound a promise to a deadline, rejecting with a TimeoutError if it does
6
+ * not settle in time. The underlying operation is not cancelled; its result
7
+ * is simply unused if it settles late.
8
+ */
9
+ export declare function withTimeout<T>(promise: Promise<T>, timeoutMs: number, label: string): Promise<T>;
@@ -14,4 +14,5 @@ export default class Config<K extends keyof FullConfig = keyof FullConfig> {
14
14
  defaults?: Partial<FullConfig>;
15
15
  }): Promise<Partial<FullConfig>>;
16
16
  static refresh(keys: (keyof FullConfig)[]): Promise<Partial<FullConfig>>;
17
+ private static persist;
17
18
  }
@@ -19,7 +19,10 @@ export declare enum WorkerMessageType {
19
19
  Mission_Invite = "mission:invite",
20
20
  Channel_Change = "channel:change",
21
21
  Feature_Update = "cloudtak:feature:update",
22
- Profile_Update = "cloudtak:profile:update"
22
+ Profile_Update = "cloudtak:profile:update",
23
+ Sync_Start = "cloudtak:sync:start",
24
+ Sync_Complete = "cloudtak:sync:complete",
25
+ Sync_Update = "cloudtak:sync:update"
23
26
  }
24
27
  export type WorkerMessage = {
25
28
  type: WorkerMessageType;
@@ -0,0 +1,17 @@
1
+ import type { ProfileOverlay } from '../types.ts';
2
+ export declare const OVERLAY_LIST_CACHE_KEY = "overlay";
3
+ /**
4
+ * Apply a single overlay (delivered inline on a sync event) to the local
5
+ * database - avoids re-listing overlays from the API, which is slow due to
6
+ * per-overlay existence checks
7
+ */
8
+ export declare function applyOverlay(overlay: ProfileOverlay): Promise<void>;
9
+ /**
10
+ * Remove a single overlay from the local database after it was deleted by
11
+ * another of the user's clients
12
+ */
13
+ export declare function removeOverlay(id: number): Promise<void>;
14
+ /**
15
+ * Refresh the local overlay database with the latest overlays from the server
16
+ */
17
+ export declare function syncOverlays(): Promise<void>;
@@ -5,16 +5,16 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
5
5
  default: number;
6
6
  };
7
7
  }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
8
- close: (...args: any[]) => void;
9
8
  click: (...args: any[]) => void;
9
+ close: (...args: any[]) => void;
10
10
  }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
11
11
  size: {
12
12
  type: NumberConstructor;
13
13
  default: number;
14
14
  };
15
15
  }>> & Readonly<{
16
- onClose?: ((...args: any[]) => any) | undefined;
17
16
  onClick?: ((...args: any[]) => any) | undefined;
17
+ onClose?: ((...args: any[]) => any) | undefined;
18
18
  }>, {
19
19
  size: number;
20
20
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
@@ -21,15 +21,15 @@ declare const __VLS_export: import("vue").DefineComponent<Props, {
21
21
  refresh: typeof refresh;
22
22
  upload: typeof upload;
23
23
  }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
24
- error: (response: Error) => any;
25
24
  cancel: () => any;
25
+ error: (response: Error) => any;
26
26
  done: (response: unknown) => any;
27
27
  staged: (response: {
28
28
  name: string;
29
29
  }) => any;
30
30
  }, string, import("vue").PublicProps, Readonly<Props> & Readonly<{
31
- onError?: ((response: Error) => any) | undefined;
32
31
  onCancel?: (() => any) | undefined;
32
+ onError?: ((response: Error) => any) | undefined;
33
33
  onDone?: ((response: unknown) => any) | undefined;
34
34
  onStaged?: ((response: {
35
35
  name: string;
@@ -12,6 +12,7 @@ export declare const useAppStore: import("pinia").StoreDefinition<"cloudtak-app"
12
12
  loadingStage: string;
13
13
  }, {}, {
14
14
  setServerUrl(serverUrl: string): Promise<void>;
15
+ mirrorServerUrl(serverUrl: string): Promise<void>;
15
16
  persistSession(opts: {
16
17
  token: string;
17
18
  username: string;
@@ -22,7 +23,7 @@ export declare const useAppStore: import("pinia").StoreDefinition<"cloudtak-app"
22
23
  clearSession(): Promise<void>;
23
24
  destroySession(): Promise<void>;
24
25
  applyTheme(style?: string): void;
25
- routeLogin(): void;
26
+ routeLogin(): Promise<void>;
26
27
  refreshLogin(): Promise<void>;
27
28
  logout(): Promise<void>;
28
29
  bootstrap(): Promise<boolean>;
@@ -127,6 +127,15 @@ export declare const useMapStore: import("pinia").StoreDefinition<"cloudtak", {
127
127
  init: (container: HTMLElement) => Promise<void>;
128
128
  submitLocationHttp: (position: Position) => Promise<void>;
129
129
  initOverlays: () => Promise<void>;
130
+ /**
131
+ * Reconcile the loaded map overlays against the local overlay
132
+ * database after a sync triggered by another of the user's connected
133
+ * clients. Adds newly created overlays, removes deleted ones and
134
+ * applies visibility/opacity changes. Changes are applied to the map
135
+ * directly (not via Overlay.update/save) so the reconcile does not
136
+ * PATCH the API and echo the event back to the originating client.
137
+ */
138
+ reconcileOverlays: () => Promise<void>;
130
139
  updateIconRotation: (enabled: boolean) => void;
131
140
  updateDistanceUnit: (unit: string) => void;
132
141
  updateAttribution: () => Promise<void>;
@@ -3,6 +3,7 @@ export default class AtlasConnection {
3
3
  atlas: Atlas;
4
4
  isDestroyed: boolean;
5
5
  isOpen: boolean;
6
+ hasConnected: boolean;
6
7
  ws: WebSocket | undefined;
7
8
  reconnectAttempts: number;
8
9
  version: string;
@@ -13,6 +13,7 @@ type NestedArray = {
13
13
  export default class AtlasDatabase {
14
14
  atlas: Atlas;
15
15
  cots: Map<string, COT>;
16
+ archiveIds: Set<string>;
16
17
  mission?: string;
17
18
  static normalizePath(path: string): string;
18
19
  pendingCreate: Map<string, COT>;
@@ -69,6 +70,14 @@ export default class AtlasDatabase {
69
70
  touching(poly: Polygon): Promise<Set<COT>>;
70
71
  /**
71
72
  * Load Archived CoTs
73
+ *
74
+ * Reconciles the local store against the server's archive: features are
75
+ * added/updated idempotently and archived features that were previously
76
+ * loaded from the server but no longer exist there (deleted by another
77
+ * client, possibly while this client was disconnected) are removed
78
+ * locally. Only ids in `archiveIds` (seen from the server on a prior
79
+ * load) are prune candidates, so a freshly drawn feature whose PUT is
80
+ * still in flight is never removed.
72
81
  */
73
82
  loadArchive(): Promise<void>;
74
83
  /**
@@ -0,0 +1,63 @@
1
+ import type Atlas from './atlas.ts';
2
+ export declare enum SyncDataType {
3
+ Overlay = "overlay",
4
+ Feature = "feature",
5
+ Mission = "mission",
6
+ Basemap = "basemap",
7
+ Iconset = "iconset",
8
+ Profile = "profile",
9
+ Contact = "contact",
10
+ Chatroom = "chatroom",
11
+ Group = "group",
12
+ MissionTemplate = "mission-template",
13
+ Server = "server"
14
+ }
15
+ export declare enum SyncEventAction {
16
+ Create = "create",
17
+ Update = "update",
18
+ Delete = "delete"
19
+ }
20
+ export type SyncEvent = {
21
+ type: SyncDataType;
22
+ action: SyncEventAction;
23
+ id?: string | number;
24
+ body?: unknown;
25
+ };
26
+ export default class AtlasSync {
27
+ atlas: Atlas;
28
+ started: boolean;
29
+ isSyncing: boolean;
30
+ lastSync: number | null;
31
+ lastErrors: string[];
32
+ private current;
33
+ private queue;
34
+ private timer;
35
+ private flushing;
36
+ constructor(atlas: Atlas);
37
+ /**
38
+ * Called by the UI once the map has initialized and finished loading,
39
+ * kicking off the initial full synchronization with the TAK Server
40
+ */
41
+ start(): Promise<void>;
42
+ /**
43
+ * Perform a full synchronization of all data types. Concurrent calls
44
+ * coalesce onto the in-flight sync.
45
+ */
46
+ fullSync(): Promise<void>;
47
+ /**
48
+ * Entry point for sync events received over the WebSocket from
49
+ * AtlasConnection - queues the event and processes it after a short
50
+ * debounce so bursts of events result in a single sync per data type
51
+ */
52
+ event(event: SyncEvent): Promise<void>;
53
+ destroy(): void;
54
+ private runFullSync;
55
+ private flush;
56
+ private syncEvent;
57
+ /**
58
+ * Fetch a single archived feature by id from the API and apply it to the
59
+ * local store. If the feature no longer exists (deleted between the event
60
+ * firing and this fetch) it is removed locally instead.
61
+ */
62
+ private syncFeature;
63
+ }
@@ -3,6 +3,7 @@ import * as Comlink from 'comlink';
3
3
  import AtlasProfile from './atlas-profile.ts';
4
4
  import AtlasDatabase from './atlas-database.ts';
5
5
  import AtlasConnection from './atlas-connection.ts';
6
+ import AtlasSync from './atlas-sync.ts';
6
7
  export default class Atlas {
7
8
  channel: BroadcastChannel;
8
9
  token: string;
@@ -11,6 +12,7 @@ export default class Atlas {
11
12
  db: AtlasDatabase & Comlink.ProxyMarked;
12
13
  conn: AtlasConnection & Comlink.ProxyMarked;
13
14
  profile: AtlasProfile & Comlink.ProxyMarked;
15
+ sync: AtlasSync & Comlink.ProxyMarked;
14
16
  constructor();
15
17
  postMessage(msg: WorkerMessage): Promise<void>;
16
18
  init(authToken: string): Promise<void>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tak-ps/cloudtak",
3
3
  "type": "module",
4
- "version": "13.30.1",
4
+ "version": "13.32.0",
5
5
  "types": "dist/types/plugin.d.ts",
6
6
  "files": [
7
7
  "dist/types"