Skip to content

Commit bc3d504

Browse files
committed
feat(HDSSettings): memory-only mode when not hooked
set / setDynamic no longer throw when there is no Pryv connection; they update the in-memory cache only (so subsequent get() reads back the value). Useful for standalone demos that don't bind to an account but still want the settings panel to drive the UI. Pryv-bound flow is unchanged: once hookToConnection / hookToApplication runs, writes go through to events.create / events.update as before. Existing tests HDSS-S3 / HDSD10 updated from "throws when not hooked" to "memory-only when not hooked".
1 parent d2e6234 commit bc3d504

2 files changed

Lines changed: 29 additions & 13 deletions

File tree

tests/HDSSettings.test.js

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,11 @@ describe('[HDSS] HDSSettings', function () {
130130
assert.deepStrictEqual(updateCall.params.update, { content: 'dark' });
131131
});
132132

133-
it('[HDSS-S3] throws when not hooked', async () => {
134-
await assert.rejects(
135-
() => HDSSettings.set('theme', 'dark'),
136-
/hookToApplication|hookToConnection/
137-
);
133+
it('[HDSS-S3] set without hook is memory-only (no Pryv write, value cached)', async () => {
134+
// Reset singleton state — no connection means memory-only mode.
135+
// The call must not throw and a subsequent get() must return the value.
136+
await HDSSettings.set('theme', 'dark');
137+
assert.strictEqual(HDSSettings.get('theme'), 'dark');
138138
});
139139

140140
it('[HDSS-S4] displayName uses same set/get as other settings', async () => {
@@ -313,10 +313,14 @@ describe('[HDSD] HDSSettings dynamic settings', function () {
313313
);
314314
});
315315

316-
it('[HDSD10] setDynamic throws when not hooked', async () => {
316+
it('[HDSD10] setDynamic without hook is memory-only (no Pryv write, value cached)', async () => {
317+
// Memory-only mode: no connection, no error, get() reads back the value.
318+
await HDSSettings.setDynamic('preferred-display-wellbeing-mood', 'billings');
319+
assert.strictEqual(HDSSettings.get('preferred-display-wellbeing-mood'), 'billings');
320+
// Unknown prefix still throws.
317321
await assert.rejects(
318-
() => HDSSettings.setDynamic('preferred-display-wellbeing-mood', 'billings'),
319-
/hookToApplication|hookToConnection/
322+
() => HDSSettings.setDynamic('not-a-known-prefix', 'foo'),
323+
/Unknown dynamic setting prefix/
320324
);
321325
});
322326
});

ts/settings/HDSSettings.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -216,10 +216,15 @@ const HDSSettings = {
216216

217217
/**
218218
* Set a typed setting value — persists to HDS server and updates cache.
219+
* When not hooked (no Pryv connection), accepts the value into the
220+
* in-memory cache only (memory-only mode — useful for standalone demos
221+
* where settings don't need to survive the session).
219222
*/
220223
async set<K extends SettingKey> (key: K, value: SettingsValues[K]): Promise<void> {
221224
if (!_connection || !_streamId) {
222-
throw new Error('HDSSettings: call hookToApplication() or hookToConnection() first');
225+
_values[key] = value;
226+
applySideEffects(_values, key);
227+
return;
223228
}
224229

225230
const eventType = SETTING_TYPES[key];
@@ -249,15 +254,22 @@ const HDSSettings = {
249254
* Set a dynamic setting value — persists to HDS server.
250255
* Key must match a known prefix (e.g. 'preferred-display-wellbeing-mood').
251256
* Pass null to delete the setting.
257+
* When not hooked (no Pryv connection), accepts the value into the
258+
* in-memory map only (memory-only mode — useful for standalone demos).
252259
*/
253260
async setDynamic (key: string, value: any): Promise<void> {
254-
if (!_connection || !_streamId) {
255-
throw new Error('HDSSettings: call hookToApplication() or hookToConnection() first');
256-
}
257-
258261
const dp = findDynamicPrefix(key);
259262
if (!dp) throw new Error(`Unknown dynamic setting prefix for key: "${key}"`);
260263

264+
if (!_connection || !_streamId) {
265+
if (value === null || value === undefined) {
266+
delete _dynamicValues[key];
267+
} else {
268+
_dynamicValues[key] = value;
269+
}
270+
return;
271+
}
272+
261273
const existing = _dynamicCache[key];
262274

263275
if (value === null || value === undefined) {

0 commit comments

Comments
 (0)