@cube-nl/dmp-sdk 1.1.0-rc.2 → 1.1.0-rc.4
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 +41 -14
- package/dist/app.d.ts +2 -2
- package/dist/app.js +1 -1
- package/dist/cube-sdk.js +24 -21
- package/dist/cube-ui.manifest.json +35 -5
- package/dist/size.json +2 -2
- package/dist/ui/attributes.js +1 -1
- package/dist/ui/blocks/board.d.ts +1 -1
- package/dist/ui/blocks/board.js +75 -3
- package/dist/ui/manifest.d.ts +4 -1
- package/dist/ui/manifest.js +21 -3
- package/dist/ui/trial-banner.d.ts +2 -0
- package/dist/ui/trial-banner.js +39 -6
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -50,9 +50,9 @@ For an app without a build step, the single-file browser build is on the npm CDN
|
|
|
50
50
|
version:
|
|
51
51
|
|
|
52
52
|
```html
|
|
53
|
-
<script src="https://cdn.jsdelivr.net/npm/@cube-nl/dmp-sdk@1.1.0-rc.
|
|
53
|
+
<script src="https://cdn.jsdelivr.net/npm/@cube-nl/dmp-sdk@1.1.0-rc.4/dist/cube-sdk.js"></script>
|
|
54
54
|
<!-- or -->
|
|
55
|
-
<script src="https://unpkg.com/@cube-nl/dmp-sdk@1.1.0-rc.
|
|
55
|
+
<script src="https://unpkg.com/@cube-nl/dmp-sdk@1.1.0-rc.4/dist/cube-sdk.js"></script>
|
|
56
56
|
```
|
|
57
57
|
|
|
58
58
|
Fallback, for an unreleased commit: `npm install
|
|
@@ -616,16 +616,31 @@ apply to it):
|
|
|
616
616
|
keeps it out of storage, logs and an innocent `innerHTML` dump; it is no defence against hostile code in the page,
|
|
617
617
|
which the DMP bounds instead (read-only, bound to the maker's IP and `Origin: null`, at most 60 minutes).
|
|
618
618
|
- **The banner.** `cube-sdk.js` puts `<cube-trial-banner>` first in `<body>` (shadow DOM, constructable stylesheet,
|
|
619
|
-
house-style tokens): *"Proefversie · alleen jij · alleen lezen · verloopt om 15:42 · leest: orders, klanten ·
|
|
620
|
-
geen gegevens uit deze proefversie in je AI-gesprek."*
|
|
619
|
+
house-style tokens): *"Proefversie · alleen jij · alleen lezen · verloopt om 15:42 CEST · leest: orders, klanten ·
|
|
620
|
+
Plak geen gegevens uit deze proefversie in je AI-gesprek."*
|
|
621
|
+
- **Which clock.** The time shown is the DMP's expiry moment (`expiresAt` from the page's config), formatted in the
|
|
622
|
+
page's language (`<html lang>`, nl-NL by default, like the app page in the DMP) in the browser's time zone with that
|
|
623
|
+
zone's short name (a browser in UTC shows "13:42 UTC"). The app page in the DMP formats the same moment the same way
|
|
624
|
+
(the viewer's zone, the page's language, the zone name), so both show the same time; before its script runs, and
|
|
625
|
+
without JavaScript, the app page shows the DMP's zone with that zone's name.
|
|
626
|
+
The banner ends as expired without a request when the browser's clock passes `expiresAt`; a `401 trial_expired`
|
|
627
|
+
from the DMP ends it whatever the browser's clock says. The DMP's refusal is what ends the trial: a browser clock
|
|
628
|
+
that runs behind only shows the expired state later, and one that runs ahead shows "verlopen" early while the DMP
|
|
629
|
+
would still answer.
|
|
621
630
|
- **The poll.** It asks `GET statusUrl` (with the token, `cache: 'no-store'`, a 10 s timeout) every 5 s while the
|
|
622
631
|
page is visible and every 60 s while hidden, and right away when the page becomes visible again. When `expiresAt`
|
|
623
|
-
passes it shows the expired state without a request.
|
|
632
|
+
passes it shows the expired state without a request. A `429` with a `Retry-After` in whole seconds (digits only)
|
|
633
|
+
makes the next request wait that long, at least the normal interval and at most 60 s (`RETRY_AFTER_CAP_MS`), and
|
|
634
|
+
never past `expiresAt`; while that back-off holds, becoming visible again waits out its rest instead of asking at
|
|
635
|
+
once; it covers only the request it delays. Another `Retry-After` (absent, an HTTP date) keeps the normal rhythm.
|
|
636
|
+
The page can only read `Retry-After` when the DMP exposes it (`cube/apps` does by default for trial requests, via
|
|
637
|
+
`Access-Control-Expose-Headers`); without it the normal rhythm holds.
|
|
624
638
|
|
|
625
639
|
| Answer | Banner |
|
|
626
640
|
|---|---|
|
|
627
641
|
| `200` | Nothing changes, polling goes on |
|
|
628
|
-
| Network error, timeout, `
|
|
642
|
+
| Network error, timeout, `5xx` | Polling goes on |
|
|
643
|
+
| `429` | Polling goes on, after a numeric `Retry-After` (capped at 60 s) when it is longer than the interval |
|
|
629
644
|
| `401 trial_replaced`, `wider: false` | *"Nieuwe versie wordt geladen…"*, then `location.assign(newer)` |
|
|
630
645
|
| `401 trial_replaced`, otherwise | *"Er is een nieuwe versie die meer gegevens leest."* with **Laden**: only the maker's click navigates |
|
|
631
646
|
| `401 trial_elsewhere` | *"Laad de pagina opnieuw."* with **Opnieuw laden** |
|
|
@@ -674,7 +689,7 @@ Without them the preview is permissive: every field, every function; only a fiel
|
|
|
674
689
|
|---|---|
|
|
675
690
|
| `CubeApp.connect(options?)` | `Promise<CubeAppSession>`. Options: `mock`, `manifest` (an object, or `false` to check nothing), `pageUrl` (default the page's URL), `fetch`, `tokenStorage` (`'session'`, the default, or `'memory'`), `autoSignIn` (default `false`) |
|
|
676
691
|
| `CubeApp.mock(data)` | Registers preview data for the next `connect()`; `null` forgets it |
|
|
677
|
-
| `CubeApp.version` | This SDK's version, e.g. `'1.1.0-rc.
|
|
692
|
+
| `CubeApp.version` | This SDK's version, e.g. `'1.1.0-rc.4'` |
|
|
678
693
|
| `CubeApp.sdk` | The manifest `"sdk"` this build serves, `'1'` |
|
|
679
694
|
| `session.mode` | `'preview'`, `'live'` or `'trial'` (a proefversie the DMP serves: the maker's own data, read-only, with a token written into the page) |
|
|
680
695
|
| `session.user()` | `{ id, name, scopes }` or `null` |
|
|
@@ -702,8 +717,8 @@ app with a build (route A).
|
|
|
702
717
|
| | |
|
|
703
718
|
|---|---|
|
|
704
719
|
| File | `dist/cube-sdk.js` in the package, `@cube-nl/dmp-sdk/cube-sdk.js` as an export; on jsDelivr/unpkg as `@cube-nl/dmp-sdk@<version>/dist/cube-sdk.js`; the CI's `pack` job also keeps it as an artifact |
|
|
705
|
-
| Size |
|
|
706
|
-
| Version | The banner's first line, `/*! @cube-nl/dmp-sdk 1.1.0-rc.
|
|
720
|
+
| Size | 136.3 KiB minified, 45.9 KiB gzipped (17.7 KiB core + 28.2 KiB blocks and the trial banner) in 1.1.0-rc.4; `dist/size.json` has the exact numbers |
|
|
721
|
+
| Version | The banner's first line, `/*! @cube-nl/dmp-sdk 1.1.0-rc.4 cube-sdk.js … */`, and `CubeApp.version` |
|
|
707
722
|
|
|
708
723
|
Pin it by copying the built file of a known version into the host, rather than fetching it at
|
|
709
724
|
runtime: `npm pack @cube-nl/dmp-sdk@<version>` downloads the tarball, `package/dist/cube-sdk.js` is
|
|
@@ -764,9 +779,17 @@ await CubeApp.connect();
|
|
|
764
779
|
|
|
765
780
|
The manifest `dist/cube-ui.manifest.json` (export `@cube-nl/dmp-sdk/cube-ui.manifest.json`) lists every element
|
|
766
781
|
with its attributes, events, an example and the version it appeared in (`since`), plus the 27 theme tokens and
|
|
767
|
-
the fonts. Its shape is final for 1.1. It is what Claude reads to compose an app.
|
|
768
|
-
|
|
769
|
-
build
|
|
782
|
+
the fonts. Its shape is final for 1.1; keys may be added. It is what Claude reads to compose an app.
|
|
783
|
+
|
|
784
|
+
The build also writes `dist/size.json` (`core_gzip`, `total_gzip`, `ui_gzip`, `budget_gzip`): the blocks may add at
|
|
785
|
+
most 40 KiB gzipped to the core and the build fails above it.
|
|
786
|
+
|
|
787
|
+
Every block lists its `actions` (everything it can use on its `resource`) and, right after it, `optional_actions`:
|
|
788
|
+
the members of `actions` the block works without (`[]` when none). The `uses` an app needs for a block is
|
|
789
|
+
`actions` minus `optional_actions`, plus an optional action only when the app uses that feature: a `cube-board`
|
|
790
|
+
that moves cards needs `update`, a `cube-detail` with `editable` needs `update`. A view-only board needs only `list`
|
|
791
|
+
and a read-only detail only `get`. The rule works on the block's `actions`; the `actions` of an attribute only
|
|
792
|
+
say which attribute uses an action (`editable` uses `update`).
|
|
770
793
|
|
|
771
794
|
### Huisstijl
|
|
772
795
|
|
|
@@ -842,12 +865,12 @@ blocks work from 320 px wide.
|
|
|
842
865
|
| `cube-top` | `resource`, `measure`, `by` (required), `limit`, `order`, `label`, `format`, `currency`, `filter`, `period`, `date-field`, `lookup`. Sorted and cut in the browser (an aggregate cannot be sorted by the API). Over 1000 groups the DMP refuses the aggregate (`422 cardinality_exceeded`, reason `too_many_groups`); the block then asks for a shorter period or a filter, without a retry. Event `cube-select` |
|
|
843
866
|
| `cube-field` | `name` (required), `label`, `format` (`text`, `number`, `integer`, `currency`, `percent`, `date`, `datetime`, `boolean`), `multiline`, `options` (`value=Label,...`), `hidden`. A configuration element, a direct child of `cube-table`, `cube-detail`, `cube-form` or `cube-board`; it is never rendered. Live `_capabilities` carries no `format` or `enum`, so a date column or a choice filter there comes from `format`/`options` here or from the values themselves, never from a guess at the type |
|
|
844
867
|
| `cube-table` | `resource` (required), `fields`, `search` (one field, box "Zoeken"), `filters` (a control per field: choices, Alle/Ja/Nee, from-to dates or numbers, else contains), `sort` (`-` for descending), `page-size` (default 25, at most 200), `export`, `detail` (selector of a `cube-detail`), `filter`, `period`, `date-field`. Needs `list`. Search waits 300 ms and the last answer wins. The rows are one Tab stop: arrow keys, Home and End move between rows; Enter or Space chooses one, which stays marked (`aria-current`). Event `cube-select` |
|
|
845
|
-
| `cube-detail` | `resource` (required), `record-id`, `fields`, `editable`. Needs `get
|
|
868
|
+
| `cube-detail` | `resource` (required), `record-id`, `fields`, `editable`. Needs `get`; `update` is optional and needed only for `editable`. Events `cube-saved`, `cube-data-change` |
|
|
846
869
|
| `cube-form` | `resource` (required), `fields`, `submit-label` (default "Opslaan"), `success-text` (default "Opgeslagen. Dank je wel!"). Needs `create`. Events `cube-created`, `cube-data-change` |
|
|
847
870
|
| `cube-calc` | `label`. A calculator that needs no data: an editor per `cube-input`, an output per `cube-result`, recalculated on every keystroke by the `formula` property. Read-only `values` and `results`, event `cube-change` (`{ values, results }`) |
|
|
848
871
|
| `cube-input` | `name`, `label` (required), `type` (`number`, `integer`, `currency`, `percent`, `text`, `select`, `checkbox`), `value`, `min`, `max`, `step`, `options` (a select needs it; `value=Label,...` as in `cube-field`). A configuration element, a direct child of `cube-calc`; it is never rendered. Numbers are typed the Dutch way (`7,5`) |
|
|
849
872
|
| `cube-result` | `name`, `label` (required), `format` (`number`, `integer`, `currency`, `percent`, `text`), `currency` (default `EUR`), `emphasis` (the large figure). A configuration element, a direct child of `cube-calc`; it is never rendered |
|
|
850
|
-
| `cube-board` | `resource`, `status-field`, `title-field` (required), `fields` (extra lines on a card), `sort`, `filter`, `page-size` (default 50, at most 200; a column with more says "en nog N"). `cube-field` children label and format the `fields` of a card. Cards in a column per status value. `status-field` must be filterable and `sort` a sortable field. Needs `list`; `update` is optional (without it the board is read-only). Event `cube-move` (`{ resource, id, from, to }`), followed by `cube-data-change` |
|
|
873
|
+
| `cube-board` | `resource`, `status-field`, `title-field` (required), `fields` (extra lines on a card), `sort`, `filter`, `page-size` (default 50, at most 200; a column with more says "en nog N"), `detail` (selector of a `cube-detail`). `cube-field` children label and format the `fields` of a card. Cards in a column per status value. `status-field` must be filterable and `sort` a sortable field. Needs `list`; `update` is optional (`optional_actions`; without it the board is read-only). Event `cube-move` (`{ resource, id, from, to }`), followed by `cube-data-change`; event `cube-select` (`{ resource, id, row }`) when a card is chosen |
|
|
851
874
|
| `cube-column` | `value` (required), `label`. A configuration element, a direct child of `cube-board`, in order; it is never rendered |
|
|
852
875
|
|
|
853
876
|
`cube-table`, `cube-detail` and `cube-form` need the matching actions in the app's `uses`
|
|
@@ -938,6 +961,10 @@ say so ("Te veel groepen…") and ask for a shorter period or a filter, without
|
|
|
938
961
|
gets the column value as a number.
|
|
939
962
|
- **Read-only**: without `update` in the app's `uses`, when the status field is read-only, or when the resource has no
|
|
940
963
|
`id` field (the board then does not request `id`), cards cannot move and show no buttons.
|
|
964
|
+
- **Choosing**: a click on a card, or Enter or Space while the card itself has focus, chooses it: `cube-select` with
|
|
965
|
+
`{ resource, id, row }` (as `cube-table`), and `detail` sets the `record-id` of that `cube-detail`. A move (a
|
|
966
|
+
button or a drop) is never a choice. The chosen card stays marked (`aria-current`) across a move and a reload until
|
|
967
|
+
another `resource` is shown; a card without `id` emits `id: null`, is not marked and fills no detail.
|
|
941
968
|
Columns stack on a narrow screen (from 320 px).
|
|
942
969
|
|
|
943
970
|
### Wireframe
|
package/dist/app.d.ts
CHANGED
|
@@ -115,8 +115,8 @@ export declare const CubeApp: Readonly<{
|
|
|
115
115
|
ready: typeof ready;
|
|
116
116
|
mock: typeof mock;
|
|
117
117
|
theme: typeof theme;
|
|
118
|
-
/** This SDK's version, e.g. `'1.1.0-rc.
|
|
119
|
-
version: "1.1.0-rc.
|
|
118
|
+
/** This SDK's version, e.g. `'1.1.0-rc.4'`. */
|
|
119
|
+
version: "1.1.0-rc.4";
|
|
120
120
|
/** The manifest `"sdk"` value this build serves. */
|
|
121
121
|
sdk: "1";
|
|
122
122
|
}>;
|
package/dist/app.js
CHANGED
|
@@ -476,7 +476,7 @@ export const CubeApp = Object.freeze({
|
|
|
476
476
|
ready,
|
|
477
477
|
mock,
|
|
478
478
|
theme,
|
|
479
|
-
/** This SDK's version, e.g. `'1.1.0-rc.
|
|
479
|
+
/** This SDK's version, e.g. `'1.1.0-rc.4'`. */
|
|
480
480
|
version: VERSION,
|
|
481
481
|
/** The manifest `"sdk"` value this build serves. */
|
|
482
482
|
sdk: MANIFEST_SDK,
|