@voxgig/build 4.4.0 → 4.12.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.
Files changed (100) hide show
  1. package/README.md +51 -2
  2. package/build.ts +20 -0
  3. package/dist/api/api_gen.d.ts +7 -0
  4. package/dist/api/api_gen.js +370 -0
  5. package/dist/api/api_gen.js.map +1 -0
  6. package/dist/build.d.ts +16 -1
  7. package/dist/build.js +17 -1
  8. package/dist/build.js.map +1 -1
  9. package/dist/doc/doc_gen.d.ts +8 -0
  10. package/dist/doc/doc_gen.js +397 -0
  11. package/dist/doc/doc_gen.js.map +1 -0
  12. package/dist/env/web/web_gen.js +197 -11
  13. package/dist/env/web/web_gen.js.map +1 -1
  14. package/dist/shape/ent.js +4 -2
  15. package/dist/shape/ent.js.map +1 -1
  16. package/env/web/web_gen.ts +219 -13
  17. package/package.json +6 -9
  18. package/tm/web/backend/env/shared/seed.ts.frag +23 -0
  19. package/tm/web/backend/env/web/api.ts.frag +157 -0
  20. package/tm/web/backend/env/web/web.ts.frag +43 -8
  21. package/tm/web/backend/srv/api/api-srv.ts.frag +4 -0
  22. package/tm/web/backend/srv/api/expose.ts.frag +33 -0
  23. package/tm/web/backend/srv/api/get_info.ts.frag +6 -0
  24. package/tm/web/backend/srv/api/on_ent.ts.frag +124 -0
  25. package/tm/web/backend/srv/auth/apikey_util.ts.frag +10 -0
  26. package/tm/web/backend/srv/auth/auth-srv.ts.frag +1 -0
  27. package/tm/web/backend/srv/auth/change_pass.ts.frag +12 -0
  28. package/tm/web/backend/srv/auth/create_apikey.ts.frag +33 -0
  29. package/tm/web/backend/srv/auth/get_info.ts.frag +1 -0
  30. package/tm/web/backend/srv/auth/list_apikey.ts.frag +15 -0
  31. package/tm/web/backend/srv/auth/load_auth.ts.frag +10 -1
  32. package/tm/web/backend/srv/auth/remind_pass.ts.frag +35 -0
  33. package/tm/web/backend/srv/auth/revoke_apikey.ts.frag +23 -0
  34. package/tm/web/backend/srv/auth/signin_user.ts.frag +12 -2
  35. package/tm/web/backend/srv/auth/signout_user.ts.frag +11 -1
  36. package/tm/web/backend/srv/auth/update_user.ts.frag +15 -0
  37. package/tm/web/backend/srv/auth/user_util.ts.frag +21 -0
  38. package/tm/web/backend/srv/auth/web_change_pass.ts.frag +16 -0
  39. package/tm/web/backend/srv/auth/web_create_apikey.ts.frag +15 -0
  40. package/tm/web/backend/srv/auth/web_list_apikey.ts.frag +11 -0
  41. package/tm/web/backend/srv/auth/web_load_auth.ts.frag +1 -0
  42. package/tm/web/backend/srv/auth/web_remind_pass.ts.frag +7 -0
  43. package/tm/web/backend/srv/auth/web_revoke_apikey.ts.frag +14 -0
  44. package/tm/web/backend/srv/auth/web_signin_user.ts.frag +1 -0
  45. package/tm/web/backend/srv/auth/web_signout_user.ts.frag +11 -3
  46. package/tm/web/backend/srv/auth/web_update_user.ts.frag +11 -0
  47. package/tm/web/backend/srv/ent/access.ts.frag +179 -0
  48. package/tm/web/backend/srv/ent/cmd_list.ts.frag +86 -0
  49. package/tm/web/backend/srv/ent/cmd_load.ts.frag +56 -0
  50. package/tm/web/backend/srv/ent/cmd_remove.ts.frag +60 -0
  51. package/tm/web/backend/srv/ent/cmd_save.ts.frag +141 -0
  52. package/tm/web/backend/srv/ent/ent-srv.ts.frag +4 -0
  53. package/tm/web/backend/srv/ent/get_info.ts.frag +6 -0
  54. package/tm/web/backend/srv/ent/web_cmd_list.ts.frag +17 -0
  55. package/tm/web/backend/srv/ent/web_cmd_load.ts.frag +17 -0
  56. package/tm/web/backend/srv/ent/web_cmd_remove.ts.frag +17 -0
  57. package/tm/web/backend/srv/ent/web_cmd_save.ts.frag +17 -0
  58. package/tm/web/backend/test/unit/env/web/api-router.test.ts.frag +315 -0
  59. package/tm/web/backend/test/unit/env/web/surface.test.ts.frag +109 -0
  60. package/tm/web/backend/test/unit/srv/api/api.setup.ts.frag +162 -0
  61. package/tm/web/backend/test/unit/srv/api/api.test.ts.frag +225 -0
  62. package/tm/web/backend/test/unit/srv/auth/apikey.test.ts.frag +152 -0
  63. package/tm/web/backend/test/unit/srv/auth/auth.setup.ts.frag +40 -0
  64. package/tm/web/backend/test/unit/srv/auth/session.test.ts.frag +189 -0
  65. package/tm/web/backend/test/unit/srv/ent/ent.setup.ts.frag +53 -0
  66. package/tm/web/backend/test/unit/srv/ent/proxy.test.ts.frag +109 -0
  67. package/tm/web/docs/explanation/web-architecture.md.frag +50 -0
  68. package/tm/web/docs/how-to/add-a-custom-entity-view.md.frag +53 -0
  69. package/tm/web/docs/how-to/change-the-theme.md.frag +63 -0
  70. package/tm/web/docs/how-to/customise-the-web-app.md.frag +68 -0
  71. package/tm/web/docs/how-to/use-the-api.md.frag +53 -0
  72. package/tm/web/docs/reference/web-app.md.frag +98 -0
  73. package/tm/web/web/AGENTS.md.frag +52 -0
  74. package/tm/web/web/e2e/smoke.spec.js.frag +13 -11
  75. package/tm/web/web/index.html.frag +1 -0
  76. package/tm/web/web/package.json.frag +1 -0
  77. package/tm/web/web/playwright.config.js.frag +2 -1
  78. package/tm/web/web/src/api.js.frag +92 -0
  79. package/tm/web/web/src/bus.js.frag +14 -8
  80. package/tm/web/web/src/cmp/admin.js.frag +293 -212
  81. package/tm/web/web/src/cmp/admin.md.frag +51 -0
  82. package/tm/web/web/src/cmp/app.js.frag +12 -15
  83. package/tm/web/web/src/cmp/app.md.frag +28 -0
  84. package/tm/web/web/src/cmp/auth.js.frag +69 -41
  85. package/tm/web/web/src/cmp/auth.md.frag +36 -0
  86. package/tm/web/web/src/cmp/public.js.frag +58 -0
  87. package/tm/web/web/src/cmp/public.md.frag +26 -0
  88. package/tm/web/web/src/cmp/settings.js.frag +178 -0
  89. package/tm/web/web/src/cmp/settings.md.frag +30 -0
  90. package/tm/web/web/src/cmp/shell.js.frag +231 -0
  91. package/tm/web/web/src/cmp/shell.md.frag +49 -0
  92. package/tm/web/web/src/cmp/view/custom-view.js.frag +47 -0
  93. package/tm/web/web/src/cmp/view/custom-view.md.frag +31 -0
  94. package/tm/web/web/src/custom.css.frag +8 -0
  95. package/tm/web/web/src/customise.js.frag +30 -0
  96. package/tm/web/web/src/hooks.js.frag +79 -0
  97. package/tm/web/web/src/main.js.frag +17 -4
  98. package/tm/web/web/src/model.js.frag +162 -0
  99. package/tm/web/web/src/style.css.frag +135 -21
  100. package/tm/web/web/src/theme.js.frag +82 -0
@@ -0,0 +1,98 @@
1
+ # Reference: the web app
2
+
3
+ *Diátaxis: reference — the generated SPA's structure, messages, hook
4
+ points, and theme contract.*
5
+
6
+ ## Files ($$fe$$/src/)
7
+
8
+ | File | Role | Regenerated? |
9
+ |---|---|---|
10
+ | `main.js` | Entry: imports css, bus, components, views, customise | no |
11
+ | `bus.js` | The browser Seneca bus (transport to the backend gateway) | no |
12
+ | `model.js` | Runtime model: fetches `/model.json`; entities, refs graph, labels, project scoping, custom-view tags | no |
13
+ | `api.js` | Client for `aim:ent` CRUD + `aim:auth` | no |
14
+ | `hooks.js` | Customisation hook registry | no |
15
+ | `theme.js` | Theme mode controller (persisted; applies `data-theme-mode`) | no |
16
+ | `style.css` | App styles (consume `--vg-*` variables) | no |
17
+ | `theme.css` | CSS variables per theme mode | **yes — from the model** |
18
+ | `views.js` | Index importing custom entity views | **yes — from the model** |
19
+ | `customise.js` / `custom.css` | Project customisations | no (yours) |
20
+ | `cmp/app.js` | Router: signed-out → public, signed-in → shell | no |
21
+ | `cmp/public.js` | Public site + login mount | no |
22
+ | `cmp/auth.js` | Login / forgot-password form | no |
23
+ | `cmp/shell.js` | App shell: topbar, project selector, user menu, entity nav | no |
24
+ | `cmp/admin.js` | Generic entity admin (list/detail/form, relationship drill) | no |
25
+ | `cmp/settings.js` | Profile + change password | no |
26
+ | `cmp/view/*.js` | Custom entity views (one per `ux:{view:'custom'}` entity) | no (starters) |
27
+
28
+ ## Backend messages used
29
+
30
+ **The browser may only send `aim:web` messages.** The gateway allow-list
31
+ names that one namespace, and every message the SPA sends is declared in
32
+ the model as an `aim:web` PROXY that forwards to the real service message
33
+ (`web_*` action files). Service namespaces (`aim:auth`, `aim:ent`,
34
+ `aim:api`, ...) are internal: posting one from a browser is rejected with
35
+ `not-allowed`. API-key clients have the same shape - the REST router
36
+ posts `aim:api`, which is likewise not browser-reachable.
37
+
38
+ | Browser message | Proxies to | Purpose |
39
+ |---|---|---|
40
+ | `aim:web,on:ent,cmd:list,ent:<canon>` (+`q`) | `aim:ent,cmd:list` | List (membership/project-scoped) |
41
+ | `aim:web,on:ent,cmd:load,ent:<canon>` (+`id`) | `aim:ent,cmd:load` | Load one |
42
+ | `aim:web,on:ent,cmd:save,ent:<canon>` (+`item`) | `aim:ent,cmd:save` | Create/update |
43
+ | `aim:web,on:ent,cmd:remove,ent:<canon>` (+`id`) | `aim:ent,cmd:remove` | Delete |
44
+ | `aim:web,on:auth,load:auth` | `aim:auth,load:auth` | Current principal |
45
+ | `aim:web,on:auth,signin:user` / `signout:user` | `aim:auth,*` | Session (sets/clears the cookie) |
46
+ | `aim:web,on:auth,change:pass` / `update:user` | `aim:auth,*` | Settings & security |
47
+ | `aim:web,on:auth,remind:pass` | `aim:auth,remind:pass` | Password reminder (server stub) |
48
+ | `aim:web,on:auth,create:apikey` / `list:apikey` / `revoke:apikey` | `aim:auth,*` | API keys |
49
+
50
+ To expose a new operation to the browser, declare an `aim:web` proxy for
51
+ it in the model and implement the `web_*` action - never widen the
52
+ allow-list.
53
+
54
+ ## Hook points
55
+
56
+ Register in `customise.js`; kinds: `html` (inject markup), `filter`
57
+ (transform a value), `action` (side effect). All synchronous,
58
+ failure-isolated.
59
+
60
+ | Point | Kind | Context / value |
61
+ |---|---|---|
62
+ | `shell:topbar:right` | html | `{ user }` |
63
+ | `shell:sidebar:top` | html | `{ user }` |
64
+ | `shell:nav:items` | filter | entity list for the nav menu |
65
+ | `admin:list:toolbar` | html | list toolbar region |
66
+ | `admin:list:items` | filter | rows before render |
67
+ | `admin:list:columns` | filter | column defs |
68
+ | `admin:row:actions` | html | per-row action cell |
69
+ | `admin:list:after` | action | `{ root, canon, items }` |
70
+ | `admin:form:fields` | filter | form field defs |
71
+ | `admin:form:extra` | html | extra form markup |
72
+ | `admin:form:after` | action | after form render |
73
+ | `admin:save:data` | filter | payload before save |
74
+ | `admin:save:after` | action | after successful save |
75
+ | `public:sections` | html | extra public-site sections |
76
+ | `auth:form:footer` | html | login form footer |
77
+ | `settings:sections` | html | extra settings sections |
78
+ | `theme:modes` | filter | available theme mode list |
79
+
80
+ ## Theme contract
81
+
82
+ - Model: `main.theme` = `{ mode, modes: { <name>: { <token>: <value> } } }`
83
+ (source: `backend/model/theme.aontu`).
84
+ - Generated CSS: each token → `--vg-<token>` under
85
+ `:root[data-theme-mode="<name>"]`; default mode also on `:root`.
86
+ - Runtime: `theme.js` sets `data-theme-mode` on `<html>`; choice persists
87
+ in localStorage `vg-theme-mode`; shell user menu toggles when more than
88
+ one mode exists.
89
+ - Standard tokens: `primary`, `primary-dark`, `bg`, `surface`, `text`,
90
+ `muted`, `border`, `topbar-bg`, `topbar-fg`, `accent-bg`, `font`,
91
+ `radius`, `shadow-card`.
92
+
93
+ ## Custom entity view contract
94
+
95
+ Tag `vg-view-<zone>-<name>`; properties `canon`, `projectId`, `detailId`,
96
+ `onNavigate(canon, id)`; method `reload()`. Declared by
97
+ `ux: { view: 'custom' }` on the model entity.
98
+
@@ -0,0 +1,52 @@
1
+ # Agent guide: $$name$$ web app
2
+
3
+ The model-driven SPA for $$name$$: vanilla web components on a browser
4
+ Seneca message bus (no framework). Generated once by @voxgig/build EnvWeb;
5
+ now developer-owned. Backend guide: ../AGENTS.md. Concept docs:
6
+ ../docs/ (see reference/web-app.md and explanation/web-architecture.md).
7
+
8
+ ## Commands (run in web/)
9
+
10
+ ```bash
11
+ npm install
12
+ npm run dev # vite dev server (backend must be running: npm run web in backend/)
13
+ npm run e2e # playwright e2e (headless; starts its own backend)
14
+ ```
15
+
16
+ E2e tests run headless Chromium with workers=1 against a shared backend —
17
+ keep new specs independent of execution order but tolerant of shared seed
18
+ data.
19
+
20
+ ## Architecture in one paragraph
21
+
22
+ `main.js` imports theme/css, the bus, all components, `views.js`
23
+ (generated index of custom views), and `customise.js` (project hooks).
24
+ All data flows are Seneca messages on `bus.js`. **Only `aim:web`
25
+ messages leave the browser** - that is the sole namespace the gateway
26
+ accepts, and each one is a declared proxy to a real service message;
27
+ `cmp:*` and events stay local. The transport pin is `aim:web` too, so a
28
+ stray service-message post fails locally instead of travelling. The UI is
29
+ model-driven at runtime — `model.js` fetches `/model.json` and derives
30
+ the entity menu, forms, and relationship navigation; `api.js` wraps the
31
+ `aim:web,on:ent,cmd:*` CRUD proxies and the `aim:web,on:auth,*` proxies.
32
+
33
+ ## Editing rules
34
+
35
+ - Everything here is create-once EXCEPT `src/views.js` and
36
+ `src/theme.css` — those are REGENERATED from the model
37
+ (`npm run model-build` in backend/); never hand-edit them. Theme tokens
38
+ live in `backend/model/theme.aontu`; per-project overrides in
39
+ `src/custom.css`.
40
+ - Prefer customisation over editing generated components: hooks in
41
+ `src/customise.js` (see `src/hooks.js` for points), CSS variables in
42
+ `src/custom.css`, or a custom entity view (`ux:{view:'custom'}` in the
43
+ model). Edit components directly only when those layers can't express
44
+ the change.
45
+ - Components re-render by setting `innerHTML`; async renders must guard
46
+ against stale overwrites (see the render-token pattern in
47
+ `cmp/admin.js`: capture a token at method start, bail before writing if
48
+ superseded).
49
+ - `bus.sub` has no auto-unsubscribe: long-lived subscriptions in
50
+ components must guard callbacks with `this.isConnected`.
51
+ - Escape all user data with the local `esc()` helpers when building HTML.
52
+
@@ -1,21 +1,23 @@
1
1
  import { test, expect } from '@playwright/test'
2
2
 
3
- // Generic smoke test: the SPA boots, a seeded user can sign in, and the
4
- // model-driven entity admin renders with at least one entity. Add
5
- // project-specific CRUD flows alongside this file.
3
+ // Generic smoke test: the public site loads, a seeded user can sign in, and
4
+ // the model-driven app shell renders with an entity menu. Add project-specific
5
+ // flows (CRUD, relationship drill, settings) in your own spec files.
6
6
 
7
- test('sign in and load the entity admin', async ({ page }) => {
7
+ test('public site, sign in, and the app shell', async ({ page }) => {
8
8
  await page.goto('/')
9
9
 
10
+ // Public content site with a login form.
10
11
  await expect(page.locator('vg-auth h2')).toHaveText('Sign in')
11
12
 
12
- await page.fill('input[name=email]', '$$seedEmail$$')
13
- await page.fill('input[name=password]', '$$seedPassword$$')
13
+ await page.fill('vg-auth input[name=email]', '$$seedEmail$$')
14
+ await page.fill('vg-auth input[name=password]', '$$seedPassword$$')
14
15
  await page.click('vg-auth button[type=submit]')
15
16
 
16
- await expect(page.locator('.vg-auth-bar b')).toHaveText('$$seedEmail$$')
17
- await expect(page.locator('vg-entity-admin nav a')).not.toHaveCount(0)
18
-
19
- // The first entity's list loads (count line rendered).
20
- await expect(page.locator('#vg-count')).toBeVisible()
17
+ // The enterprise shell: top bar with the signed-in user, and a
18
+ // model-driven entity menu with at least one entity.
19
+ await expect(page.locator('.vg-shell')).toBeVisible()
20
+ await expect(page.locator('.vg-user-btn')).toContainText('$$seedEmail$$')
21
+ await expect(page.locator('.vg-navlink')).not.toHaveCount(0)
21
22
  })
23
+
@@ -13,3 +13,4 @@
13
13
  <script type="module" src="/src/main.js"></script>
14
14
  </body>
15
15
  </html>
16
+
@@ -17,3 +17,4 @@
17
17
  "vite": "^7.3.4"
18
18
  }
19
19
  }
20
+
@@ -30,7 +30,7 @@ export default defineConfig({
30
30
  },
31
31
  ],
32
32
  webServer: {
33
- command: `npm run build && cd ../backend && PORT=${PORT} node dist/env/web/web.js`,
33
+ command: `npm run build && cd ../backend && PORT=${PORT} REPL=false node dist/env/web/web.js`,
34
34
  url: `http://localhost:${PORT}/`,
35
35
  timeout: 60000,
36
36
  reuseExistingServer: false,
@@ -38,3 +38,4 @@ export default defineConfig({
38
38
  stderr: 'pipe',
39
39
  },
40
40
  })
41
+
@@ -0,0 +1,92 @@
1
+ // Thin client over the Seneca bus.
2
+ //
3
+ // EVERY message the browser sends is an aim:web message: that is the only
4
+ // namespace the backend gateway accepts (see backend/src/env/web/web.ts),
5
+ // and each one is a declared proxy that forwards to the real service
6
+ // message. Entity CRUD still lands on the ONE generic backend service, so
7
+ // the same four calls serve every entity in the model.
8
+
9
+ import { bus } from './bus.js'
10
+
11
+ // ---- generic entity CRUD ------------------------------------------------
12
+
13
+ async function list(ent, q) {
14
+ const r = await bus.post({ aim: 'web', on: 'ent', cmd: 'list', ent, q: q || {} })
15
+ return (r && r.ok && r.list) || []
16
+ }
17
+
18
+ async function load(ent, id) {
19
+ const r = await bus.post({ aim: 'web', on: 'ent', cmd: 'load', ent, id })
20
+ return r && r.ok ? r.item : null
21
+ }
22
+
23
+ async function save(ent, item) {
24
+ return bus.post({ aim: 'web', on: 'ent', cmd: 'save', ent, item })
25
+ }
26
+
27
+ async function remove(ent, id) {
28
+ return bus.post({ aim: 'web', on: 'ent', cmd: 'remove', ent, id })
29
+ }
30
+
31
+ // Users, for reference pickers (read-only, public fields).
32
+ async function users() {
33
+ return list('sys/user')
34
+ }
35
+
36
+ // ---- auth / settings ----------------------------------------------------
37
+
38
+ async function loadAuth() {
39
+ return bus.post('aim:web,on:auth,load:auth')
40
+ }
41
+
42
+ async function signin(email, password) {
43
+ return bus.post('aim:web,on:auth,signin:user', { email, password })
44
+ }
45
+
46
+ async function signout() {
47
+ return bus.post('aim:web,on:auth,signout:user')
48
+ }
49
+
50
+ async function changePass(password) {
51
+ return bus.post({ aim: 'web', on: 'auth', change: 'pass', password })
52
+ }
53
+
54
+ async function updateUser(data) {
55
+ return bus.post({ aim: 'web', on: 'auth', update: 'user', data })
56
+ }
57
+
58
+ async function remindPass(email) {
59
+ return bus.post({ aim: 'web', on: 'auth', remind: 'pass', email })
60
+ }
61
+
62
+ // ---- API access keys (REST API auth; Settings & security) ---------------
63
+
64
+ async function createApikey(name) {
65
+ return bus.post({ aim: 'web', on: 'auth', create: 'apikey', name })
66
+ }
67
+
68
+ async function listApikeys() {
69
+ return bus.post({ aim: 'web', on: 'auth', list: 'apikey' })
70
+ }
71
+
72
+ async function revokeApikey(id) {
73
+ return bus.post({ aim: 'web', on: 'auth', revoke: 'apikey', id })
74
+ }
75
+
76
+ export {
77
+ list,
78
+ load,
79
+ save,
80
+ remove,
81
+ users,
82
+ loadAuth,
83
+ signin,
84
+ signout,
85
+ changePass,
86
+ updateUser,
87
+ remindPass,
88
+ createApikey,
89
+ listApikeys,
90
+ revokeApikey,
91
+ }
92
+
@@ -1,7 +1,7 @@
1
1
  // The browser-side Seneca service bus. All component state and all
2
2
  // backend communication flow through messages on this bus:
3
3
  //
4
- // aim:* -> the backend gateway (/seneca) via the
4
+ // aim:web,* -> the backend gateway (/seneca) via the
5
5
  // seneca-browser fetch transport (cookie auth)
6
6
  // cmp:* -> local component plugins (state)
7
7
  //
@@ -23,22 +23,27 @@ const bus = Seneca({
23
23
  },
24
24
  })
25
25
  .test()
26
- .client({ type: 'browser', pin: 'aim:*' })
26
+ .client({ type: 'browser', pin: 'aim:web' })
27
27
 
28
28
 
29
- // Transparent state cache (Redux-like): caches aim:* query results and
29
+ // Transparent state cache (Redux-like): caches aim:web query results and
30
30
  // invalidates on writes, so repeated reads are served without a round-trip.
31
- // Registered AFTER .client() so the aim:* pin actions exist to be wrapped.
31
+ // Registered AFTER .client() so the aim:web pin actions exist to be wrapped.
32
32
  if ('undefined' !== typeof SenecaBrowserStore) {
33
- bus.use(SenecaBrowserStore, { pin: 'aim:*' })
33
+ bus.use(SenecaBrowserStore, {
34
+ pin: 'aim:web',
35
+ // Defaults plus 'revoke': aim:web,on:auth,revoke:apikey must
36
+ // invalidate the cached list:apikey reads.
37
+ write: ['save', 'remove', 'update', 'delete', 'create', 'done', 'set', 'add', 'revoke'],
38
+ })
34
39
  }
35
40
 
36
41
  // In-window devtools: a resizable/hideable pop-up showing live Seneca
37
42
  // message flows, config, and (via the store plugin above) the cache tree.
38
- // aim:* messages are the remote (backend) calls. Loaded as a global script
43
+ // aim:web messages are the remote (backend) calls. Loaded as a global script
39
44
  // in index.html; guarded so a missing bundle never breaks the app.
40
45
  if ('undefined' !== typeof SenecaBrowserDebug) {
41
- bus.use(SenecaBrowserDebug, { remotePins: 'aim:*' })
46
+ bus.use(SenecaBrowserDebug, { remotePins: 'aim:web' })
42
47
  }
43
48
 
44
49
 
@@ -75,4 +80,5 @@ export {
75
80
  bus,
76
81
  onEvent,
77
82
  emit,
78
- }
83
+ }
84
+