@tak-ps/cloudtak 13.16.1 → 13.18.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.
@@ -0,0 +1,53 @@
1
+ /**
2
+ * FeatureManager provides methods for managing Features in both the API
3
+ * and the dexie database. It is designed implement BaseInterface and
4
+ * provides additional methods specific to the Feature entity, such as counting,
5
+ * listing with filters, downloading, and deleting features.
6
+ *
7
+ * Note that it currently does not handle re-rendering calls in the map stack and therefore
8
+ * must be used in conjunction with the cot.ts module or atlas-database.ts to ensure
9
+ * that re-rendering is triggered.
10
+ */
11
+ import { type Observable } from 'dexie';
12
+ import { type DBFeature } from '../database.ts';
13
+ import type { paths } from '@cloudtak/api-types';
14
+ import BaseInterface from './interface.ts';
15
+ import type { BaseInterface_ListOptions, BaseInterface_FromOptions } from './interface.ts';
16
+ type FeatureListQuery = NonNullable<paths['/api/profile/feature']['get']['parameters']['query']>;
17
+ type FeatureDeleteQuery = NonNullable<paths['/api/profile/feature']['delete']['parameters']['query']>;
18
+ export type Feature_ExportFormat = FeatureListQuery['format'];
19
+ export type Feature_ListOptions = BaseInterface_ListOptions & {
20
+ path?: string;
21
+ filter?: string;
22
+ };
23
+ export type Feature_FromOptions = BaseInterface_FromOptions;
24
+ export type Feature_DeleteOptions = {
25
+ path?: FeatureDeleteQuery['path'];
26
+ permanent?: FeatureDeleteQuery['permanent'];
27
+ };
28
+ export type Feature_DownloadOptions = {
29
+ format?: Feature_ExportFormat;
30
+ };
31
+ export default class FeatureManager extends BaseInterface {
32
+ static readonly listCacheKey = "feature";
33
+ static count(): Promise<number>;
34
+ static liveCount(): Observable<number>;
35
+ static liveList(): Observable<DBFeature[]>;
36
+ static list(opts?: Feature_ListOptions): Promise<DBFeature[]>;
37
+ static from(id: string, opts?: Feature_FromOptions): Promise<DBFeature | undefined>;
38
+ static liveFrom(id: string): Observable<DBFeature | undefined>;
39
+ /**
40
+ * Export the profile features from the server and trigger a browser download.
41
+ *
42
+ * @param opts.format - The export format to request (defaults to GeoJSON)
43
+ */
44
+ static download(opts?: Feature_DownloadOptions): Promise<void>;
45
+ /**
46
+ * Delete profile features on the server.
47
+ *
48
+ * Without a `path`, all of the user's features are removed. By default features
49
+ * are archived (soft deleted) unless `permanent` is set.
50
+ */
51
+ static delete(opts?: Feature_DeleteOptions): Promise<void>;
52
+ }
53
+ export {};
@@ -67,5 +67,5 @@ export default class BaseInterface {
67
67
  *
68
68
  * @param id - The unique identifier of the item to delete
69
69
  */
70
- static delete(id: string): Promise<void>;
70
+ static delete(id?: unknown): Promise<void>;
71
71
  }
@@ -0,0 +1,45 @@
1
+ import type Subscription from './subscription.ts';
2
+ import type { MissionLayer, MissionLayer_Create, MissionLayer_Update } from '../types.ts';
3
+ /**
4
+ * High Level Wrapper around the Data/Mission Sync Layer API
5
+ *
6
+ * Layers are hydrated from the server and persisted in the local Dexie
7
+ * `subscription_layer` table so that they can be observed reactively via
8
+ * liveQuery.
9
+ */
10
+ export default class SubscriptionLayer {
11
+ parent: Subscription;
12
+ token: string;
13
+ missiontoken?: string;
14
+ constructor(parent: Subscription, opts: {
15
+ token: string;
16
+ missiontoken?: string;
17
+ });
18
+ headers(): Record<string, string>;
19
+ /**
20
+ * Hard refresh the mission layers from the server and persist them
21
+ * in the local Dexie store.
22
+ */
23
+ refresh(): Promise<void>;
24
+ /**
25
+ * List the mission layers from the local store.
26
+ *
27
+ * @param opts - Options for listing the layers
28
+ * @param opts.refresh - If true, refresh from the server before listing
29
+ */
30
+ list(opts?: {
31
+ refresh?: boolean;
32
+ }): Promise<Array<MissionLayer>>;
33
+ /**
34
+ * Create a new mission layer, then refresh the local store.
35
+ */
36
+ create(layer: MissionLayer_Create): Promise<MissionLayer>;
37
+ /**
38
+ * Update an existing mission layer, then refresh the local store.
39
+ */
40
+ update(layerid: string, layer: MissionLayer_Update): Promise<MissionLayer>;
41
+ /**
42
+ * Delete a mission layer, then refresh the local store.
43
+ */
44
+ delete(layeruid: string): Promise<void>;
45
+ }
@@ -2,8 +2,9 @@ import SubscriptionLog from './subscription-log.ts';
2
2
  import SubscriptionChanges from './subscription-changes.ts';
3
3
  import SubscriptionContents from './subscription-contents.ts';
4
4
  import SubscriptionFeature from './subscription-feature.ts';
5
+ import SubscriptionLayer from './subscription-layer.ts';
5
6
  import SubscriptionChat from './subscription-chat.ts';
6
- import type { Mission, MissionRole, MissionList, MissionLayer, MissionLayerList, MissionLayer_Create, MissionLayer_Update, MissionSubscriptions, MissionInvite } from '../types.ts';
7
+ import type { Mission, MissionRole, MissionList, MissionSubscriptions, MissionInvite } from '../types.ts';
7
8
  export declare enum SubscriptionEventType {
8
9
  CREATE = "subscription::create",
9
10
  UPDATE = "subscription::update",
@@ -38,6 +39,7 @@ export default class Subscription {
38
39
  change: SubscriptionChanges;
39
40
  contents: SubscriptionContents;
40
41
  feature: SubscriptionFeature;
42
+ layer: SubscriptionLayer;
41
43
  chat: SubscriptionChat;
42
44
  token: string;
43
45
  missiontoken?: string;
@@ -123,8 +125,4 @@ export default class Subscription {
123
125
  }): Promise<void>;
124
126
  removeUser(uid: string): Promise<void>;
125
127
  subscriptions(): Promise<MissionSubscriptions>;
126
- layerList(): Promise<MissionLayerList>;
127
- layerUpdate(layerid: string, layer: MissionLayer_Update): Promise<MissionLayer>;
128
- layerCreate(layer: MissionLayer_Create): Promise<MissionLayer>;
129
- layerDelete(layeruid: string): Promise<void>;
130
128
  }
@@ -1,10 +1,10 @@
1
1
  import type { Component, PropType } from 'vue';
2
2
  type LayoutVariant = 'list' | 'tiles';
3
- declare var __VLS_10: {}, __VLS_17: {};
3
+ declare var __VLS_11: {}, __VLS_18: {};
4
4
  type __VLS_Slots = {} & {
5
- prefix?: (props: typeof __VLS_10) => any;
5
+ prefix?: (props: typeof __VLS_11) => any;
6
6
  } & {
7
- default?: (props: typeof __VLS_17) => any;
7
+ default?: (props: typeof __VLS_18) => any;
8
8
  };
9
9
  declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
10
10
  icon: {
@@ -3,11 +3,11 @@ type __VLS_Props = {
3
3
  subscription: Subscription;
4
4
  };
5
5
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
6
- cancel: (...args: any[]) => void;
7
6
  layer: (...args: any[]) => void;
7
+ cancel: (...args: any[]) => void;
8
8
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
9
- onCancel?: ((...args: any[]) => any) | undefined;
10
9
  onLayer?: ((...args: any[]) => any) | undefined;
10
+ onCancel?: ((...args: any[]) => any) | undefined;
11
11
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
12
12
  declare const _default: typeof __VLS_export;
13
13
  export default _default;
@@ -5,11 +5,11 @@ type __VLS_Props = {
5
5
  layer: MissionLayer;
6
6
  };
7
7
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
8
- cancel: (...args: any[]) => void;
9
8
  layer: (...args: any[]) => void;
9
+ cancel: (...args: any[]) => void;
10
10
  }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
11
- onCancel?: ((...args: any[]) => any) | undefined;
12
11
  onLayer?: ((...args: any[]) => any) | undefined;
12
+ onCancel?: ((...args: any[]) => any) | undefined;
13
13
  }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
14
14
  declare const _default: typeof __VLS_export;
15
15
  export default _default;
@@ -1,6 +1,6 @@
1
- declare var __VLS_23: {};
1
+ declare var __VLS_25: {};
2
2
  type __VLS_Slots = {} & {
3
- default?: (props: typeof __VLS_23) => any;
3
+ default?: (props: typeof __VLS_25) => any;
4
4
  };
5
5
  declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
6
6
  mode: {
@@ -23,6 +23,10 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
23
23
  type: BooleanConstructor;
24
24
  default: boolean;
25
25
  };
26
+ visibilityToggle: {
27
+ type: BooleanConstructor;
28
+ default: boolean;
29
+ };
26
30
  hover: {
27
31
  type: BooleanConstructor;
28
32
  default: boolean;
@@ -58,6 +62,10 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
58
62
  type: BooleanConstructor;
59
63
  default: boolean;
60
64
  };
65
+ visibilityToggle: {
66
+ type: BooleanConstructor;
67
+ default: boolean;
68
+ };
61
69
  hover: {
62
70
  type: BooleanConstructor;
63
71
  default: boolean;
@@ -76,6 +84,7 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
76
84
  deleteAction: string;
77
85
  gripHandle: boolean;
78
86
  infoButton: boolean;
87
+ visibilityToggle: boolean;
79
88
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
80
89
  declare const _default: typeof __VLS_export;
81
90
  export default _default;
@@ -3,16 +3,31 @@ declare const _default: typeof __VLS_export;
3
3
  export default _default;
4
4
  declare const __VLS_export: import("vue").DefineComponent<{
5
5
  nodes: PathNode[];
6
+ renamable?: boolean;
7
+ deletable?: boolean;
8
+ visibilityToggle?: boolean;
9
+ isNodeHidden?: (node: PathNode) => boolean;
6
10
  }, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
7
11
  navigate: (node: PathNode<any>) => any;
8
12
  delete: (node: PathNode<any>) => any;
9
13
  rename: (node: PathNode<any>) => any;
10
14
  "folder-drop": (node: PathNode<any>) => any;
15
+ "toggle-visibility": (node: PathNode<any>) => any;
11
16
  }, string, import("vue").PublicProps, Readonly<{
12
17
  nodes: PathNode[];
18
+ renamable?: boolean;
19
+ deletable?: boolean;
20
+ visibilityToggle?: boolean;
21
+ isNodeHidden?: (node: PathNode) => boolean;
13
22
  }> & Readonly<{
14
23
  onNavigate?: ((node: PathNode<any>) => any) | undefined;
15
24
  onDelete?: ((node: PathNode<any>) => any) | undefined;
16
25
  onRename?: ((node: PathNode<any>) => any) | undefined;
17
26
  "onFolder-drop"?: ((node: PathNode<any>) => any) | undefined;
18
- }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
27
+ "onToggle-visibility"?: ((node: PathNode<any>) => any) | undefined;
28
+ }>, {
29
+ visibilityToggle: boolean;
30
+ deletable: boolean;
31
+ renamable: boolean;
32
+ isNodeHidden: (node: PathNode) => boolean;
33
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
@@ -1,5 +1,5 @@
1
1
  import Dexie, { type EntityTable } from 'dexie';
2
- import type { Feature, GroupChannel, Mission, MissionRole, MissionChange, MissionLog, Contact, Server, ProfileOverlayList } from './types.ts';
2
+ import type { Feature, GroupChannel, Mission, MissionRole, MissionChange, MissionLayer, MissionLog, Contact, Server, ProfileOverlayList } from './types.ts';
3
3
  export interface DBIcon {
4
4
  /** Maplibre image id, e.g. "<iconsetUid>:<icon-path-without-extension>" */
5
5
  name: string;
@@ -101,6 +101,11 @@ export interface DBSubscriptionFeature {
101
101
  properties: Feature["properties"];
102
102
  geometry: Feature["geometry"];
103
103
  }
104
+ export interface DBSubscriptionLayer {
105
+ uid: string;
106
+ mission: string;
107
+ layer: MissionLayer;
108
+ }
104
109
  export interface DBSubscriptionContent {
105
110
  uid: string;
106
111
  mission: string;
@@ -205,6 +210,7 @@ export type DatabaseType = Dexie & {
205
210
  subscription_log: EntityTable<DBSubscriptionLog, 'id'>;
206
211
  subscription_feature: EntityTable<DBSubscriptionFeature, 'id'>;
207
212
  subscription_chat: EntityTable<DBSubscriptionChat, 'id'>;
213
+ subscription_layer: EntityTable<DBSubscriptionLayer, 'uid'>;
208
214
  mission_template: EntityTable<DBMissionTemplate, 'id'>;
209
215
  mission_template_log: EntityTable<DBMissionTemplateLog, 'id'>;
210
216
  kv: EntityTable<DBKV, 'key'>;
@@ -0,0 +1,33 @@
1
+ export default class Session {
2
+ /**
3
+ * Persist the server URL into the KV store (and Preferences on native).
4
+ */
5
+ static serverUrl(serverUrl: string): Promise<void>;
6
+ /**
7
+ * Persist login details for the authenticated user.
8
+ */
9
+ static login(opts: {
10
+ token: string;
11
+ username: string;
12
+ }): Promise<void>;
13
+ /**
14
+ * Return the username of the existing session, if one is present.
15
+ */
16
+ static username(): Promise<string | undefined>;
17
+ /**
18
+ * Remove the active token from all stores. The Dexie database is left
19
+ * intact so that a re-login (e.g. after an expired token) does not need to
20
+ * resynchronize all data.
21
+ */
22
+ static clear(): Promise<void>;
23
+ /**
24
+ * Fully clear the session - removes the token and wipes the Dexie database.
25
+ * Used on explicit sign-out or when a different user logs in.
26
+ *
27
+ * Dexie's `delete()`/`open()` is used (instead of
28
+ * `indexedDB.deleteDatabase`) so the live connection is closed cleanly and
29
+ * immediately reopened, leaving the database ready for subsequent reads and
30
+ * writes instead of hanging on a blocked delete request.
31
+ */
32
+ static destroy(): Promise<void>;
33
+ }
@@ -0,0 +1,21 @@
1
+ import type Overlay from '../../base/overlay-class.ts';
2
+ /**
3
+ * Source id used for the internal "Map Features" GeoJSON overlay that holds
4
+ * all non-mission CoTs. Mirrors the `Overlay.internal({ id: -1 })` registration.
5
+ */
6
+ export declare const GENERAL_SOURCE_ID = "-1";
7
+ export declare class FeatureVisibility {
8
+ static load(): Promise<void>;
9
+ private static persist;
10
+ static isFeatureHidden(id: string): boolean;
11
+ static isPathHidden(sourceId: string | number, path: string): boolean;
12
+ static setFeatureHidden(id: string, hidden: boolean): void;
13
+ static toggleFeature(id: string): void;
14
+ static setFeaturesHidden(ids: string[], hidden: boolean): void;
15
+ static areFeaturesHidden(ids: string[]): boolean;
16
+ static setPathHidden(sourceId: string | number, path: string, hidden: boolean): void;
17
+ static togglePath(sourceId: string | number, path: string): void;
18
+ private static buildPredicate;
19
+ static applyToOverlay(overlay: Overlay): Promise<void>;
20
+ static apply(): Promise<void>;
21
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tak-ps/cloudtak",
3
3
  "type": "module",
4
- "version": "13.16.1",
4
+ "version": "13.18.0",
5
5
  "types": "dist/types/plugin.d.ts",
6
6
  "files": [
7
7
  "dist/types"
@@ -1,15 +0,0 @@
1
- import type { MissionLayer, Feature } from '../../../../types.ts';
2
- import Subscription from '../../../../base/subscription.ts';
3
- type __VLS_Props = {
4
- layers: Array<MissionLayer>;
5
- feats: Map<string, Feature>;
6
- subscription: Subscription;
7
- orphaned?: Set<string>;
8
- };
9
- declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
10
- refresh: (...args: any[]) => void;
11
- }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
12
- onRefresh?: ((...args: any[]) => any) | undefined;
13
- }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
14
- declare const _default: typeof __VLS_export;
15
- export default _default;