@unisim/sdk 0.157.0 → 0.159.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.
- package/README.md +42 -6
- package/dist/UserCountBreakdown.d.ts +4 -1
- package/dist/UserCountBreakdown.d.ts.map +1 -1
- package/dist/UserCountBreakdown.js +165 -21
- package/dist/UserCountBreakdown.js.map +1 -1
- package/dist/i18n.d.ts.map +1 -1
- package/dist/i18n.js +116 -16
- package/dist/i18n.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/presence.d.ts +120 -9
- package/dist/presence.d.ts.map +1 -1
- package/dist/presence.js +359 -47
- package/dist/presence.js.map +1 -1
- package/dist/provider.d.ts +8 -1
- package/dist/provider.d.ts.map +1 -1
- package/dist/provider.js +8 -2
- package/dist/provider.js.map +1 -1
- package/package.json +1 -1
package/dist/presence.d.ts
CHANGED
|
@@ -9,6 +9,17 @@ export interface UserCounts {
|
|
|
9
9
|
total: number;
|
|
10
10
|
/** Of those, how many beat in the last two minutes. */
|
|
11
11
|
live: number;
|
|
12
|
+
/**
|
|
13
|
+
* Of `total`, how many were last seen in a browser / in an installed app.
|
|
14
|
+
*
|
|
15
|
+
* ⚠️ `web + native <= total`, and on a figure that has not turned over since
|
|
16
|
+
* 0.158.0 shipped it is a good deal less: a person whose last beat predates
|
|
17
|
+
* the platform column is in neither bucket. `null` where the split is not
|
|
18
|
+
* available at all — a database without migration 0187, or a product whose
|
|
19
|
+
* total comes from its own account counter (0185).
|
|
20
|
+
*/
|
|
21
|
+
web?: number | null;
|
|
22
|
+
native?: number | null;
|
|
12
23
|
}
|
|
13
24
|
/** Which figure the line is showing. Not a product code — 'suite' is all of them. */
|
|
14
25
|
export type CountScope = 'app' | 'suite';
|
|
@@ -17,6 +28,15 @@ export interface ProductCounts extends UserCounts {
|
|
|
17
28
|
/** The product_code the beat was written under — 'pdf', 'fire_assess', … */
|
|
18
29
|
product: string;
|
|
19
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* What the beat reports itself as, matching migration 0187's CHECK.
|
|
33
|
+
*
|
|
34
|
+
* ⚠️ `null` is a real answer, not a failure: it means "this install cannot say"
|
|
35
|
+
* — a Capacitor bridge that has not come up yet, or an Electron build on an OS
|
|
36
|
+
* this does not recognise. The server keeps whatever platform an earlier beat
|
|
37
|
+
* established rather than erasing it, so a single unknown beat costs nothing.
|
|
38
|
+
*/
|
|
39
|
+
export type DevicePlatform = 'web' | 'ios' | 'android' | 'windows' | 'macos' | 'linux';
|
|
20
40
|
/** ⚠️ **Legacy, and only ever deleted now.** It used to remember whichever
|
|
21
41
|
* figure a viewer last switched the line to, which meant one tap made every
|
|
22
42
|
* app on that browser open on its own figure for ever. The line now always
|
|
@@ -25,23 +45,80 @@ export interface ProductCounts extends UserCounts {
|
|
|
25
45
|
* do not carry a dead key around. */
|
|
26
46
|
export declare const COUNT_SCOPE_KEY = "unisim:user-count-scope";
|
|
27
47
|
export declare function getInstallId(): string | null;
|
|
28
|
-
/**
|
|
48
|
+
/**
|
|
49
|
+
* True in anything the person INSTALLED — a Capacitor container or an Electron
|
|
50
|
+
* desktop build — as opposed to a page they navigated to.
|
|
51
|
+
*
|
|
52
|
+
* This is what decides that the beat goes immediately rather than waiting for
|
|
53
|
+
* an interaction, so it deliberately errs towards "no": a browser wrongly
|
|
54
|
+
* treated as an app would put page loads back in the total, which is the whole
|
|
55
|
+
* thing this release takes out.
|
|
56
|
+
*
|
|
57
|
+
* ⚠️ Electron is read off `navigator.userAgent` and the preload bridge rather
|
|
58
|
+
* than imported from `desktop.ts`, which pulls React in — and this file has
|
|
59
|
+
* none on purpose (Universal AI is Svelte).
|
|
60
|
+
*/
|
|
61
|
+
export declare function isInstalledApp(): boolean;
|
|
62
|
+
/**
|
|
63
|
+
* What this install reports itself as to `app_presence_beat`.
|
|
64
|
+
*
|
|
65
|
+
* ⚠️ An installed app that cannot name its OS answers `null`, NOT `'web'`.
|
|
66
|
+
* Migration 0187 keeps the platform an earlier beat established when a beat
|
|
67
|
+
* says nothing, so an unknown is a missed chance to record rather than a wrong
|
|
68
|
+
* record — and a desktop app quietly filed under "web" is the exact figure
|
|
69
|
+
* this feature exists to get right.
|
|
70
|
+
*/
|
|
71
|
+
export declare function devicePlatform(): DevicePlatform | null;
|
|
72
|
+
/**
|
|
73
|
+
* What counts as the person doing something. A scroll and a wheel are in the
|
|
74
|
+
* list on purpose: reading a page IS using it, and a reader who never clicks
|
|
75
|
+
* is not the drive-by this gate is meant to drop.
|
|
76
|
+
*/
|
|
77
|
+
export declare const INTERACTION_EVENTS: readonly ["pointerdown", "keydown", "touchstart", "wheel", "scroll"];
|
|
78
|
+
/** Whether this page has seen a real interaction yet. Exported for tests and
|
|
79
|
+
* for an app that wants to hold something else back on the same rule. */
|
|
80
|
+
export declare function hasInteracted(): boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Run `fn` on the first interaction — or straight away if one has already
|
|
83
|
+
* happened on this page. Returns a function that cancels the wait.
|
|
84
|
+
*
|
|
85
|
+
* ⚠️ The flag is module-level, so an app that restarts presence (signing in
|
|
86
|
+
* does) does not put the gate back in front of somebody who has been clicking
|
|
87
|
+
* for ten minutes.
|
|
88
|
+
*/
|
|
89
|
+
export declare function onFirstInteraction(fn: () => void): () => void;
|
|
90
|
+
/**
|
|
91
|
+
* Report this install as here now. Never throws; resolves whether it landed.
|
|
92
|
+
*/
|
|
29
93
|
export declare function beatPresence(supabase: SupabaseClient, product: ProductCode): Promise<boolean>;
|
|
94
|
+
export interface PresenceOptions {
|
|
95
|
+
/**
|
|
96
|
+
* Web only: hold the first beat until the person interacts with the page
|
|
97
|
+
* (see {@link INTERACTION_EVENTS}). Default **true** since 0.158.0.
|
|
98
|
+
*
|
|
99
|
+
* ⚠️ Turn it off for a surface nobody touches but everybody sees — a wall
|
|
100
|
+
* display, a kiosk, a screensaver — where "loaded it" really is the whole of
|
|
101
|
+
* the usage. It does NOT need turning off for an installed app: those never
|
|
102
|
+
* wait in the first place.
|
|
103
|
+
*/
|
|
104
|
+
requireInteraction?: boolean;
|
|
105
|
+
}
|
|
30
106
|
/**
|
|
31
|
-
* Beat now,
|
|
32
|
-
*
|
|
107
|
+
* Beat now — or, on the web, at the first interaction — then every
|
|
108
|
+
* {@link PRESENCE_BEAT_MS} while the page is visible, and straight away when it
|
|
109
|
+
* becomes visible again. Returns a stop function.
|
|
33
110
|
*
|
|
34
111
|
* A hidden page does not beat: a backgrounded tab is not someone using the app,
|
|
35
112
|
* and it drops out of "live" within two minutes on its own.
|
|
36
113
|
*/
|
|
37
|
-
export declare function startPresence(supabase: SupabaseClient, product: ProductCode): () => void;
|
|
114
|
+
export declare function startPresence(supabase: SupabaseClient, product: ProductCode, options?: PresenceOptions): () => void;
|
|
38
115
|
/** The last counts this origin read for `product` (or, with 'suite', for the
|
|
39
116
|
* whole suite), or null. */
|
|
40
117
|
export declare function cachedUserCounts(product: ProductCode | 'suite'): UserCounts | null;
|
|
41
118
|
/**
|
|
42
|
-
* Read `{ total, live }` for `product`. Waits (up to 3 s) for this
|
|
43
|
-
* pending beat so the reader is in the figure. Resolves null on any
|
|
44
|
-
* the caller hides its line rather than showing a wrong number.
|
|
119
|
+
* Read `{ total, live, web, native }` for `product`. Waits (up to 3 s) for this
|
|
120
|
+
* page's pending beat so the reader is in the figure. Resolves null on any
|
|
121
|
+
* failure — the caller hides its line rather than showing a wrong number.
|
|
45
122
|
*/
|
|
46
123
|
export declare function fetchUserCounts(supabase: SupabaseClient, product: ProductCode, scope?: CountScope): Promise<UserCounts | null>;
|
|
47
124
|
/** The last breakdown this origin read, or null. Same job as
|
|
@@ -49,8 +126,9 @@ export declare function fetchUserCounts(supabase: SupabaseClient, product: Produ
|
|
|
49
126
|
* swaps it for the fresh one when it lands, rather than opening empty. */
|
|
50
127
|
export declare function cachedUserCountsByProduct(): ProductCounts[] | null;
|
|
51
128
|
/**
|
|
52
|
-
* `{ product, total, live }` for every product anybody has ever
|
|
53
|
-
* first — the breakdown behind the suite figure (migration
|
|
129
|
+
* `{ product, total, live, web, native }` for every product anybody has ever
|
|
130
|
+
* opened, biggest first — the breakdown behind the suite figure (migration
|
|
131
|
+
* 0184).
|
|
54
132
|
*
|
|
55
133
|
* Resolves null on any failure, exactly like {@link fetchUserCounts}, so a
|
|
56
134
|
* caller shows nothing rather than a wrong number. ⚠️ **That includes an app
|
|
@@ -62,12 +140,45 @@ export declare function cachedUserCountsByProduct(): ProductCounts[] | null;
|
|
|
62
140
|
* ⚠️ The rows do NOT sum to `fetchUserCounts(_, _, 'suite').total`: an account
|
|
63
141
|
* using four apps is four rows here and one person there. Never add them up to
|
|
64
142
|
* produce a total — the suite figure is the total.
|
|
143
|
+
*
|
|
144
|
+
* ⚠️ `web`/`native` are null on a row whose total comes from that app's own
|
|
145
|
+
* account counter (migration 0185, the Bipolar apps): the counter has no
|
|
146
|
+
* platform in it, so a split beside it would describe a different, smaller
|
|
147
|
+
* population than the total next to it.
|
|
65
148
|
*/
|
|
66
149
|
export declare function fetchUserCountsByProduct(supabase: SupabaseClient): Promise<ProductCounts[] | null>;
|
|
150
|
+
/** How many Universal IDs exist, and how many are in use right now (migration
|
|
151
|
+
* 0188). Anonymous guest sessions are not IDs and are not in either figure. */
|
|
152
|
+
export interface UniversalIdCounts {
|
|
153
|
+
created: number;
|
|
154
|
+
live: number;
|
|
155
|
+
}
|
|
156
|
+
/** The last Universal ID counts this origin read, or null. */
|
|
157
|
+
export declare function cachedUniversalIdCounts(): UniversalIdCounts | null;
|
|
158
|
+
/**
|
|
159
|
+
* `{ created, live }` for Universal IDs — the row at the top of the breakdown
|
|
160
|
+
* (James, 2026-09-27). Resolves null on any failure, including a database
|
|
161
|
+
* without migration 0188, so the popup leaves the row out rather than showing
|
|
162
|
+
* a wrong number.
|
|
163
|
+
*/
|
|
164
|
+
export declare function fetchUniversalIdCounts(supabase: SupabaseClient): Promise<UniversalIdCounts | null>;
|
|
165
|
+
/** "52 created", "2 live" — the Universal IDs row's figures, as separate
|
|
166
|
+
* phrases for the same reason as {@link userCountParts}. */
|
|
167
|
+
export declare function universalIdParts(language: string | null | undefined, counts: UniversalIdCounts): string[];
|
|
67
168
|
/**
|
|
68
169
|
* "There are 1,234 total users (5 live)" — or, for the 'suite' scope, "There
|
|
69
170
|
* are a total of 1,234 users across all UNI·SIM apps (5 live)" — in `language`,
|
|
70
171
|
* with the numbers grouped the way that language groups them.
|
|
71
172
|
*/
|
|
72
173
|
export declare function formatUserCounts(language: string | null | undefined, counts: UserCounts, scope?: CountScope): string;
|
|
174
|
+
/**
|
|
175
|
+
* The figures behind one row of the breakdown, as separate phrases — "1,234
|
|
176
|
+
* users", "900 web", "334 native", "5 live" — so the caller can lay them out
|
|
177
|
+
* and let them WRAP rather than measuring a single string (James, 2026-09-21:
|
|
178
|
+
* "show web | native | live if there's enough space").
|
|
179
|
+
*
|
|
180
|
+
* The split is left out entirely when it is not available, rather than shown as
|
|
181
|
+
* "0 web · 0 native": see {@link UserCounts.web}.
|
|
182
|
+
*/
|
|
183
|
+
export declare function userCountParts(language: string | null | undefined, counts: UserCounts): string[];
|
|
73
184
|
//# sourceMappingURL=presence.d.ts.map
|
package/dist/presence.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"presence.d.ts","sourceRoot":"","sources":["../src/presence.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"presence.d.ts","sourceRoot":"","sources":["../src/presence.ts"],"names":[],"mappings":"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"}
|