@zfdx123/dsh-hooks-ordering 1.0.5 → 1.0.6
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/client.js +114 -13
- package/package.json +1 -1
package/client.js
CHANGED
|
@@ -346,6 +346,73 @@
|
|
|
346
346
|
return style
|
|
347
347
|
}
|
|
348
348
|
|
|
349
|
+
/**
|
|
350
|
+
* The name this plugin's settings entry actually has, resolved at runtime
|
|
351
|
+
* from the descriptors the host returns.
|
|
352
|
+
*
|
|
353
|
+
* It CANNOT be a constant. The settings namespace is the **loader entry
|
|
354
|
+
* id**, which belongs to whoever wrote the row that mounted this plugin,
|
|
355
|
+
* not to the plugin: the aggregator's `cordis.patch.yml` uses
|
|
356
|
+
* `dsh-plugin-hooks-ordering`, while this package's own patch uses
|
|
357
|
+
* `hooks-ordering`. Hardcoding the latter against the former produced
|
|
358
|
+
*
|
|
359
|
+
* no settings entry is named "hooks-ordering" (describe() returned: …, dsh-plugin-hooks-ordering, …)
|
|
360
|
+
*
|
|
361
|
+
* and the write path was refused outright:
|
|
362
|
+
*
|
|
363
|
+
* settings/rejected: No configurable plugin entry "hooks-ordering"
|
|
364
|
+
*
|
|
365
|
+
* Matching on the descriptor's own `ns` removes the guesswork: whatever id
|
|
366
|
+
* the mounting row has, this is the entry it produced.
|
|
367
|
+
*/
|
|
368
|
+
var resolvedNs = null
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* Normalise a Remote answer to `{ ok, value }` / `{ ok: false, reason }`.
|
|
372
|
+
*
|
|
373
|
+
* The 0.1.7 Remote protocol answers every call with a `RemoteResult`
|
|
374
|
+
* envelope and the client proxy hands that envelope through as-is, so a
|
|
375
|
+
* caller that reads fields off the answer directly sees `undefined` while
|
|
376
|
+
* the wire traffic is healthy. A plain value is accepted too, so this
|
|
377
|
+
* keeps working if a future runtime unwraps for us.
|
|
378
|
+
*
|
|
379
|
+
* @param answer - whatever the Remote call resolved to.
|
|
380
|
+
* @returns the unwrapped outcome.
|
|
381
|
+
*/
|
|
382
|
+
function unwrapRemote(answer) {
|
|
383
|
+
if (answer !== null && typeof answer === 'object' && typeof answer.ok === 'boolean') {
|
|
384
|
+
if (answer.ok === false) {
|
|
385
|
+
var failure = answer.error
|
|
386
|
+
var reason =
|
|
387
|
+
failure && typeof failure === 'object'
|
|
388
|
+
? String(failure.code || 'remote error') + ': ' + String(failure.message || '')
|
|
389
|
+
: String(failure || 'remote error')
|
|
390
|
+
return { ok: false, reason: reason }
|
|
391
|
+
}
|
|
392
|
+
return { ok: true, value: answer.value }
|
|
393
|
+
}
|
|
394
|
+
return { ok: true, value: answer }
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* @param list - descriptor list from `describe()`.
|
|
399
|
+
* @returns the descriptor for this plugin, or undefined.
|
|
400
|
+
*/
|
|
401
|
+
function pickEntry(list) {
|
|
402
|
+
// Fast path: the row used this package's own documented id.
|
|
403
|
+
var direct = list.find(function (entry) {
|
|
404
|
+
return entry && entry.ns === NS
|
|
405
|
+
})
|
|
406
|
+
if (direct !== undefined) return direct
|
|
407
|
+
// Otherwise take the entry that was mounting this plugin created.
|
|
408
|
+
// `dsh-plugin-hooks-ordering` is the shipped aggregator row; the suffix
|
|
409
|
+
// test also covers a user's own row name.
|
|
410
|
+
var suffixed = list.filter(function (entry) {
|
|
411
|
+
return entry && typeof entry.ns === 'string' && entry.ns.slice(-NS.length) === NS
|
|
412
|
+
})
|
|
413
|
+
return suffixed.length === 1 ? suffixed[0] : undefined
|
|
414
|
+
}
|
|
415
|
+
|
|
349
416
|
// ── the settings page ──────────────────────────────────────────────────
|
|
350
417
|
|
|
351
418
|
/**
|
|
@@ -396,6 +463,12 @@
|
|
|
396
463
|
*/
|
|
397
464
|
function createSettingsSource(ctx) {
|
|
398
465
|
var remote = ctx && ctx.remote && ctx.remote.settings
|
|
466
|
+
/**
|
|
467
|
+
* The name this plugin's settings entry actually has is resolved at
|
|
468
|
+
* runtime by {@link pickEntry} into the module-level `resolvedNs`; see
|
|
469
|
+
* the note there for why it cannot be a constant.
|
|
470
|
+
*/
|
|
471
|
+
|
|
399
472
|
/**
|
|
400
473
|
* Why the form has no data. Kept as a concrete, user-visible string:
|
|
401
474
|
* "not available" on its own made a wiring fault indistinguishable from
|
|
@@ -431,17 +504,27 @@
|
|
|
431
504
|
return remote.describe()
|
|
432
505
|
})
|
|
433
506
|
.then(function (answer) {
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
507
|
+
// A Remote call answers with a `RemoteResult` envelope
|
|
508
|
+
// (`{ok:true, value}` / `{ok:false, error}`) and the client proxy
|
|
509
|
+
// does NOT unwrap it: reading `answer.namespaces` directly got
|
|
510
|
+
// `undefined`, which surfaced as the misleading
|
|
511
|
+
// "describe() returned no namespaces array" while the network
|
|
512
|
+
// exchange was perfectly healthy (ok:true, 20 namespaces).
|
|
513
|
+
var result = unwrapRemote(answer)
|
|
514
|
+
if (result.ok === false) {
|
|
515
|
+
return unavailableBecause('describe() failed: ' + result.reason)
|
|
437
516
|
}
|
|
438
|
-
var
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
517
|
+
var value = result.value
|
|
518
|
+
if (value === null || value === undefined) {
|
|
519
|
+
return unavailableBecause('describe() returned no value')
|
|
520
|
+
}
|
|
521
|
+
var list = Array.isArray(value.namespaces) ? value.namespaces : null
|
|
522
|
+
if (list === null) {
|
|
523
|
+
return unavailableBecause(
|
|
524
|
+
'describe() value has no namespaces array (keys: ' + Object.keys(value).join(', ') + ')',
|
|
525
|
+
)
|
|
444
526
|
}
|
|
527
|
+
var found = pickEntry(list)
|
|
445
528
|
if (found === undefined) {
|
|
446
529
|
var seen = list
|
|
447
530
|
.map(function (entry) {
|
|
@@ -450,9 +533,14 @@
|
|
|
450
533
|
.filter(Boolean)
|
|
451
534
|
.join(', ')
|
|
452
535
|
return unavailableBecause(
|
|
453
|
-
'no settings entry
|
|
536
|
+
'no settings entry for this plugin (looked for "' +
|
|
537
|
+
NS +
|
|
538
|
+
'"; describe() returned: ' +
|
|
539
|
+
(seen || 'nothing') +
|
|
540
|
+
')',
|
|
454
541
|
)
|
|
455
542
|
}
|
|
543
|
+
resolvedNs = found.ns
|
|
456
544
|
return {
|
|
457
545
|
status: 'ready',
|
|
458
546
|
available: true,
|
|
@@ -482,12 +570,22 @@
|
|
|
482
570
|
}
|
|
483
571
|
// The revision is read fresh immediately before the write so a page
|
|
484
572
|
// left open across another edit reports a conflict instead of
|
|
485
|
-
// silently overwriting it.
|
|
573
|
+
// silently overwriting it. `read()` also refreshes `resolvedNs`.
|
|
486
574
|
return read().then(function (snap) {
|
|
487
575
|
if (!snap.available) {
|
|
488
576
|
throw new Error(snap.reason || 'this plugin has no settings entry in the active profile')
|
|
489
577
|
}
|
|
490
|
-
|
|
578
|
+
if (resolvedNs === null) {
|
|
579
|
+
throw new Error('this plugin did not resolve its settings entry id')
|
|
580
|
+
}
|
|
581
|
+
// The write answers with a RemoteResult envelope as well; unwrap
|
|
582
|
+
// it so a refusal surfaces as a real message instead of looking
|
|
583
|
+
// like a successful save.
|
|
584
|
+
return remote.mutate(resolvedNs, ops, snap.revision).then(function (answer) {
|
|
585
|
+
var result = unwrapRemote(answer)
|
|
586
|
+
if (result.ok === false) throw new Error(result.reason)
|
|
587
|
+
return result.value
|
|
588
|
+
})
|
|
491
589
|
})
|
|
492
590
|
},
|
|
493
591
|
/**
|
|
@@ -503,7 +601,8 @@
|
|
|
503
601
|
if (!events || typeof events.$on !== 'function') return function () {}
|
|
504
602
|
try {
|
|
505
603
|
return events.$on('settings/document-updated', function (ns) {
|
|
506
|
-
|
|
604
|
+
// Match the resolved entry id, not the package-relative name.
|
|
605
|
+
if (ns === undefined || ns === resolvedNs || ns === NS) listener()
|
|
507
606
|
})
|
|
508
607
|
} catch (error) {
|
|
509
608
|
// A missing gateway listener must not take the page down.
|
|
@@ -796,6 +895,8 @@
|
|
|
796
895
|
exports.apply = apply
|
|
797
896
|
exports.inject = inject
|
|
798
897
|
exports.NS = NS
|
|
898
|
+
exports.pickEntry = pickEntry
|
|
899
|
+
exports.unwrapRemote = unwrapRemote
|
|
799
900
|
exports.CLASS = CLASS
|
|
800
901
|
exports.CSS = CSS
|
|
801
902
|
exports.ZH = zh
|