@owlmeans/create-app 0.1.18-rc.15 → 0.1.18-rc.17
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/package.json +2 -2
- package/template/AGENTS.md +8 -0
- package/template/_agents/skills/reuse-code/SKILL.md +1 -1
- package/template/sources/api/package.json +3 -3
- package/template/sources/api/src/app/session/add.ts +7 -6
- package/template/sources/api/src/app/session/list.ts +6 -5
- package/template/sources/api/src/app/session/remove.ts +6 -5
- package/template/sources/api/src/entrypoints.bare.ts +3 -4
- package/template/sources/api/src/entrypoints.ts +4 -7
- package/template/sources/common/package.json +6 -6
- package/template/sources/common/src/consts.ts +0 -14
- package/template/sources/common/src/entrypoints.bare.ts +2 -2
- package/template/sources/common/src/entrypoints.ts +46 -16
- package/template/sources/common/src/schemas.ts +7 -7
- package/template/sources/web/package.json +11 -11
- package/template/sources/web/src/entrypoints.bare.ts +3 -4
- package/template/sources/web/src/entrypoints.ts +8 -14
- package/template/sources/web/src/screens/session.tsx +3 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owlmeans/create-app",
|
|
3
|
-
"version": "0.1.18-rc.
|
|
3
|
+
"version": "0.1.18-rc.17",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Scaffold a fullstack OwlMeans Common app — common + api + web workspaces, shadcn UI navigation/layout, no auth, and a session-scoped in-memory resource, or --bare for the demo-free shell. Also usable programmatically via scaffold(). Deploys agent skills via @owlmeans/agent-skills by default.",
|
|
6
6
|
"type": "module",
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"template"
|
|
31
31
|
],
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@owlmeans/agent-skills": "^0.1.18-rc.
|
|
33
|
+
"@owlmeans/agent-skills": "^0.1.18-rc.14"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"@owlmeans/dep-config": "workspace:*",
|
package/template/AGENTS.md
CHANGED
|
@@ -79,6 +79,14 @@ package (in the installed packages and at https://github.com/owlmeans/common) or
|
|
|
79
79
|
already solves the problem **before** proposing a third-party library or a custom solution, and
|
|
80
80
|
simplify whatever you do write. This is required for every planning and development task.
|
|
81
81
|
|
|
82
|
+
## Runtime config advertisement
|
|
83
|
+
|
|
84
|
+
The config endpoint is default-deny. A backend config field reaches the browser only when the
|
|
85
|
+
package that owns its browser consumer imports `apiConfigPlugin({ allow, deny? })` from
|
|
86
|
+
`@owlmeans/api-config` at module scope. Name public nested fields precisely; use `every()` and a
|
|
87
|
+
nested `deny` selector when a public collection carries a credential. Databases, queues, SMTP,
|
|
88
|
+
tokens, secrets and internal addresses never belong in an `allow` selector.
|
|
89
|
+
|
|
82
90
|
## Skills
|
|
83
91
|
|
|
84
92
|
Reusable guidance lives in `.agents/skills/<name>/SKILL.md`, deployed by `@owlmeans/agent-skills`
|
|
@@ -11,12 +11,12 @@
|
|
|
11
11
|
"typecheck": "tsc -b"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@owlmeans/server-app": "^0.1.18-rc.
|
|
15
|
-
"@owlmeans/static-resource": "^0.1.18-rc.
|
|
14
|
+
"@owlmeans/server-app": "^0.1.18-rc.19",
|
|
15
|
+
"@owlmeans/static-resource": "^0.1.18-rc.10",
|
|
16
16
|
"__APP_SLUG__-common": "workspace:^"
|
|
17
17
|
},
|
|
18
18
|
"devDependencies": {
|
|
19
|
-
"@owlmeans/dep-config": "^0.1.18-rc.
|
|
19
|
+
"@owlmeans/dep-config": "^0.1.18-rc.6",
|
|
20
20
|
"@types/node": "^24.10.1",
|
|
21
21
|
"typescript": "^7.0.2"
|
|
22
22
|
}
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { randomUUID } from 'node:crypto'
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
2
|
+
import { handlers } from '@owlmeans/server-app'
|
|
3
|
+
import { session, type SessionItem } from '__APP_SLUG__-common'
|
|
4
4
|
import { SESSION_ITEMS } from '../../consts.js'
|
|
5
5
|
import type { Context } from '../../types.js'
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const
|
|
7
|
+
const handle = handlers<Context>()
|
|
8
|
+
|
|
9
|
+
export const add = handle.body(session.add, async (payload, context, request) => {
|
|
10
|
+
const { sid } = request.params
|
|
11
|
+
const resource = context.getStaticResource<SessionItem>(SESSION_ITEMS)
|
|
11
12
|
|
|
12
13
|
const item: SessionItem = {
|
|
13
14
|
id: randomUUID(),
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import { handlers } from '@owlmeans/server-app'
|
|
2
|
+
import { session, type SessionItem } from '__APP_SLUG__-common'
|
|
3
3
|
import { SESSION_ITEMS } from '../../consts.js'
|
|
4
4
|
import type { Context } from '../../types.js'
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
const handle = handlers<Context>()
|
|
7
|
+
|
|
8
|
+
export const list = handle.params(session.list, async (params, context) => {
|
|
9
|
+
const resource = context.getStaticResource<SessionItem>(SESSION_ITEMS)
|
|
9
10
|
|
|
10
11
|
// The resource answers the whole question — this session's items, newest first.
|
|
11
12
|
const { items } = await resource.list(
|
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import
|
|
1
|
+
import { handlers } from '@owlmeans/server-app'
|
|
2
|
+
import { session, type SessionItem } from '__APP_SLUG__-common'
|
|
3
3
|
import { SESSION_ITEMS } from '../../consts.js'
|
|
4
4
|
import type { Context } from '../../types.js'
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
const handle = handlers<Context>()
|
|
7
|
+
|
|
8
|
+
export const remove = handle.params(session.remove, async (params, context) => {
|
|
9
|
+
const resource = context.getStaticResource<SessionItem>(SESSION_ITEMS)
|
|
9
10
|
|
|
10
11
|
const existing = await resource.load(params.id)
|
|
11
12
|
// Only remove the item if it belongs to the requesting session.
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { entrypoints } from '@owlmeans/server-app'
|
|
1
|
+
import { elevate, entrypoints } from '@owlmeans/server-app'
|
|
2
2
|
import { sharedEntrypoints } from '__APP_SLUG__-common'
|
|
3
3
|
|
|
4
|
-
// Handlers
|
|
5
|
-
|
|
6
|
-
export const appEntrypoints = [...entrypoints, ...sharedEntrypoints]
|
|
4
|
+
// Handlers bind to a protocol; a bare shell starts without any implementations.
|
|
5
|
+
export const appEntrypoints = [...entrypoints, ...elevate(sharedEntrypoints, [])]
|
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
import { elevate, entrypoints } from '@owlmeans/server-app'
|
|
2
|
-
import {
|
|
2
|
+
import { sessionEntrypoints } from '__APP_SLUG__-common'
|
|
3
3
|
import * as handlers from './app/session/index.js'
|
|
4
4
|
|
|
5
|
-
//
|
|
6
|
-
elevate(sessionEntrypoints,
|
|
7
|
-
elevate(sessionEntrypoints, session.list, handlers.list)
|
|
8
|
-
elevate(sessionEntrypoints, session.add, handlers.add)
|
|
9
|
-
elevate(sessionEntrypoints, session.remove, handlers.remove)
|
|
5
|
+
// Each handler is already bound to its protocol; elevation materializes the local server entries.
|
|
6
|
+
const sessionModules = elevate(sessionEntrypoints, [handlers.list, handlers.add, handlers.remove])
|
|
10
7
|
|
|
11
|
-
export const appEntrypoints = [...entrypoints, ...
|
|
8
|
+
export const appEntrypoints = [...entrypoints, ...sessionModules]
|
|
@@ -19,15 +19,15 @@
|
|
|
19
19
|
"typecheck": "tsc -b"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@owlmeans/config": "^0.1.18-rc.
|
|
23
|
-
"@owlmeans/entrypoint": "^0.1.18-rc.
|
|
24
|
-
"@owlmeans/error": "^0.1.18-rc.
|
|
25
|
-
"@owlmeans/resource": "^0.1.18-rc.
|
|
26
|
-
"@owlmeans/route": "^0.1.18-rc.
|
|
22
|
+
"@owlmeans/config": "^0.1.18-rc.13",
|
|
23
|
+
"@owlmeans/entrypoint": "^0.1.18-rc.12",
|
|
24
|
+
"@owlmeans/error": "^0.1.18-rc.9",
|
|
25
|
+
"@owlmeans/resource": "^0.1.18-rc.10",
|
|
26
|
+
"@owlmeans/route": "^0.1.18-rc.10",
|
|
27
27
|
"ajv": "^8.17.1"
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
|
-
"@owlmeans/dep-config": "^0.1.18-rc.
|
|
30
|
+
"@owlmeans/dep-config": "^0.1.18-rc.6",
|
|
31
31
|
"@types/node": "^24.10.1",
|
|
32
32
|
"typescript": "^7.0.2"
|
|
33
33
|
}
|
|
@@ -6,17 +6,3 @@ export const APP_API = '__APP_SLUG__-api'
|
|
|
6
6
|
/** Local development ports. */
|
|
7
7
|
export const WEB_PORT = 3001
|
|
8
8
|
export const API_PORT = 3000
|
|
9
|
-
|
|
10
|
-
/** Backend (API) entrypoint identifiers. */
|
|
11
|
-
export const session = {
|
|
12
|
-
base: '__APP_SLUG__:api:session',
|
|
13
|
-
list: '__APP_SLUG__:api:session:list',
|
|
14
|
-
add: '__APP_SLUG__:api:session:add',
|
|
15
|
-
remove: '__APP_SLUG__:api:session:remove',
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/** Frontend (web) entrypoint identifiers. */
|
|
19
|
-
export const web = {
|
|
20
|
-
session: '__APP_SLUG__:web:session',
|
|
21
|
-
about: '__APP_SLUG__:web:about',
|
|
22
|
-
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { EntrypointProtocol } from '@owlmeans/entrypoint'
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* The entrypoint declarations both sides share: the api elevates them with handlers, the web
|
|
5
5
|
* elevates them with screens or just calls them. Routes resolve under the api service `base`
|
|
6
6
|
* (`/api`), so an `entrypoint(route(alias, '/items', ...))` added here answers on `/api/items`.
|
|
7
7
|
*/
|
|
8
|
-
export const sharedEntrypoints:
|
|
8
|
+
export const sharedEntrypoints: EntrypointProtocol[] = []
|
|
@@ -1,26 +1,56 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { route, RouteMethod } from '@owlmeans/route'
|
|
3
|
-
import { session } from './consts.js'
|
|
1
|
+
import { contract, openProtocol, protocol, protocols, typed } from '@owlmeans/entrypoint'
|
|
2
|
+
import { route, RouteMethod, frontend } from '@owlmeans/route'
|
|
4
3
|
import { AddItemSchema, ItemParamsSchema, SessionParamsSchema } from './schemas.js'
|
|
5
|
-
import type {
|
|
4
|
+
import type { SessionItem } from './types.js'
|
|
5
|
+
|
|
6
|
+
const aliases = {
|
|
7
|
+
session: {
|
|
8
|
+
base: '__APP_SLUG__:api:session',
|
|
9
|
+
list: '__APP_SLUG__:api:session:list',
|
|
10
|
+
add: '__APP_SLUG__:api:session:add',
|
|
11
|
+
remove: '__APP_SLUG__:api:session:remove',
|
|
12
|
+
},
|
|
13
|
+
web: {
|
|
14
|
+
base: '__APP_SLUG__:web:base',
|
|
15
|
+
home: '__APP_SLUG__:web:home',
|
|
16
|
+
session: '__APP_SLUG__:web:session',
|
|
17
|
+
about: '__APP_SLUG__:web:about',
|
|
18
|
+
},
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const sessionBase = protocol(route(aliases.session.base, '/session'), contract())
|
|
22
|
+
const webBase = openProtocol(route(aliases.web.base, '/', frontend()))
|
|
6
23
|
|
|
7
24
|
/**
|
|
8
25
|
* Shared entrypoint declarations. The api elevates these with handlers; the web
|
|
9
26
|
* elevates them with screen components and calls them. Routes resolve under the
|
|
10
27
|
* api service `base` (`/api`), so e.g. `session.list` → `GET /api/session/:sid/items`.
|
|
11
28
|
*/
|
|
12
|
-
export const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
route(session.list, '/:sid/items', { parent:
|
|
16
|
-
|
|
29
|
+
export const session = {
|
|
30
|
+
base: sessionBase,
|
|
31
|
+
list: protocol(
|
|
32
|
+
route(aliases.session.list, '/:sid/items', { parent: sessionBase, method: RouteMethod.GET }),
|
|
33
|
+
contract.request({ params: SessionParamsSchema }, typed<SessionItem[]>()),
|
|
17
34
|
),
|
|
18
|
-
|
|
19
|
-
route(session.add, '/:sid/items', { parent:
|
|
20
|
-
|
|
35
|
+
add: protocol(
|
|
36
|
+
route(aliases.session.add, '/:sid/items', { parent: sessionBase, method: RouteMethod.POST }),
|
|
37
|
+
contract.request({
|
|
38
|
+
params: SessionParamsSchema,
|
|
39
|
+
body: AddItemSchema,
|
|
40
|
+
}, typed<SessionItem>()),
|
|
21
41
|
),
|
|
22
|
-
|
|
23
|
-
route(session.remove, '/:sid/items/:id', { parent:
|
|
24
|
-
|
|
42
|
+
remove: protocol(
|
|
43
|
+
route(aliases.session.remove, '/:sid/items/:id', { parent: sessionBase, method: RouteMethod.DELETE }),
|
|
44
|
+
contract.request({ params: ItemParamsSchema }, typed<{ removed: boolean }>()),
|
|
25
45
|
),
|
|
26
|
-
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Frontend routes are protocol declarations too; their renderer is bound by the web project. */
|
|
49
|
+
export const web = {
|
|
50
|
+
base: webBase,
|
|
51
|
+
home: openProtocol(route(aliases.web.home, '/', frontend({ default: true, parent: webBase }))),
|
|
52
|
+
session: openProtocol(route(aliases.web.session, '/session', frontend({ parent: webBase }))),
|
|
53
|
+
about: openProtocol(route(aliases.web.about, '/about', frontend({ parent: webBase }))),
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export const sessionEntrypoints = protocols(session)
|
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { schema } from '@owlmeans/entrypoint'
|
|
2
2
|
import type { AddItemPayload, ItemParams, SessionParams } from './types.js'
|
|
3
3
|
|
|
4
|
-
export const AddItemSchema
|
|
4
|
+
export const AddItemSchema = schema<AddItemPayload>({
|
|
5
5
|
type: 'object',
|
|
6
6
|
properties: {
|
|
7
7
|
text: { type: 'string', minLength: 1, maxLength: 280 },
|
|
8
8
|
},
|
|
9
9
|
required: ['text'],
|
|
10
10
|
additionalProperties: false,
|
|
11
|
-
}
|
|
11
|
+
})
|
|
12
12
|
|
|
13
|
-
export const SessionParamsSchema
|
|
13
|
+
export const SessionParamsSchema = schema<SessionParams>({
|
|
14
14
|
type: 'object',
|
|
15
15
|
properties: {
|
|
16
16
|
sid: { type: 'string', minLength: 1 },
|
|
17
17
|
},
|
|
18
18
|
required: ['sid'],
|
|
19
19
|
additionalProperties: false,
|
|
20
|
-
}
|
|
20
|
+
})
|
|
21
21
|
|
|
22
|
-
export const ItemParamsSchema
|
|
22
|
+
export const ItemParamsSchema = schema<ItemParams>({
|
|
23
23
|
type: 'object',
|
|
24
24
|
properties: {
|
|
25
25
|
sid: { type: 'string', minLength: 1 },
|
|
@@ -27,4 +27,4 @@ export const ItemParamsSchema: JSONSchemaType<ItemParams> = {
|
|
|
27
27
|
},
|
|
28
28
|
required: ['sid', 'id'],
|
|
29
29
|
additionalProperties: false,
|
|
30
|
-
}
|
|
30
|
+
})
|
|
@@ -11,16 +11,16 @@
|
|
|
11
11
|
"preview": "vite preview"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@owlmeans/client": "^0.1.18-rc.
|
|
15
|
-
"@owlmeans/client-config": "^0.1.18-rc.
|
|
16
|
-
"@owlmeans/client-context": "^0.1.18-rc.
|
|
17
|
-
"@owlmeans/client-entrypoint": "^0.1.18-rc.
|
|
18
|
-
"@owlmeans/client-i18n": "^0.1.18-rc.
|
|
19
|
-
"@owlmeans/entrypoint": "^0.1.18-rc.
|
|
20
|
-
"@owlmeans/route": "^0.1.18-rc.
|
|
21
|
-
"@owlmeans/state": "^0.1.18-rc.
|
|
22
|
-
"@owlmeans/web-client": "^0.1.18-rc.
|
|
23
|
-
"@owlmeans/web-panel": "^0.1.18-rc.
|
|
14
|
+
"@owlmeans/client": "^0.1.18-rc.17",
|
|
15
|
+
"@owlmeans/client-config": "^0.1.18-rc.13",
|
|
16
|
+
"@owlmeans/client-context": "^0.1.18-rc.14",
|
|
17
|
+
"@owlmeans/client-entrypoint": "^0.1.18-rc.14",
|
|
18
|
+
"@owlmeans/client-i18n": "^0.1.18-rc.16",
|
|
19
|
+
"@owlmeans/entrypoint": "^0.1.18-rc.12",
|
|
20
|
+
"@owlmeans/route": "^0.1.18-rc.10",
|
|
21
|
+
"@owlmeans/state": "^0.1.18-rc.11",
|
|
22
|
+
"@owlmeans/web-client": "^0.1.18-rc.25",
|
|
23
|
+
"@owlmeans/web-panel": "^0.1.18-rc.33",
|
|
24
24
|
"@radix-ui/react-label": "^2.1.0",
|
|
25
25
|
"@radix-ui/react-navigation-menu": "^1.2.14",
|
|
26
26
|
"@radix-ui/react-progress": "^1.1.0",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"tailwindcss": "^4.1.13"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@owlmeans/dep-config": "^0.1.18-rc.
|
|
42
|
+
"@owlmeans/dep-config": "^0.1.18-rc.6",
|
|
43
43
|
"@tailwindcss/vite": "^4.1.13",
|
|
44
44
|
"@types/react": "^19.2.17",
|
|
45
45
|
"@types/react-dom": "^19.2.3",
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import { BASE, entrypoint, entrypoints as baseEntrypoints, frontend, handler, HOME, route } from '@owlmeans/web-panel'
|
|
1
|
+
import { BASE, bind, entrypoint, entrypoints as baseEntrypoints, frontend, handler, HOME, route } from '@owlmeans/web-panel'
|
|
2
2
|
import { sharedEntrypoints } from '__APP_SLUG__-common'
|
|
3
3
|
import { MainLayout } from './layout/main.js'
|
|
4
4
|
import { HomeScreen } from './screens/home.js'
|
|
5
5
|
|
|
6
|
-
// Backend
|
|
7
|
-
|
|
8
|
-
const entrypoints = [...baseEntrypoints, ...sharedEntrypoints]
|
|
6
|
+
// Backend protocol declarations are materialized locally so each can be called from the browser.
|
|
7
|
+
const entrypoints = [...baseEntrypoints, ...sharedEntrypoints.map(protocol => bind(protocol))]
|
|
9
8
|
|
|
10
9
|
// Frontend layout + screens. BASE renders the shared layout; HOME is its default child.
|
|
11
10
|
entrypoints.push(entrypoint(route(BASE, '/', frontend()), handler(MainLayout)))
|
|
@@ -1,22 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { session,
|
|
1
|
+
import { bindAll, bindScreen, entrypoints as baseEntrypoints, handler } from '@owlmeans/web-panel'
|
|
2
|
+
import { session, web } from '__APP_SLUG__-common'
|
|
3
3
|
import { MainLayout } from './layout/main.js'
|
|
4
4
|
import { AboutScreen } from './screens/about.js'
|
|
5
5
|
import { HomeScreen } from './screens/home.js'
|
|
6
6
|
import { SessionScreen } from './screens/session.js'
|
|
7
7
|
|
|
8
|
-
const entrypoints = [...baseEntrypoints, ...
|
|
8
|
+
const entrypoints = [...baseEntrypoints, ...bindAll(session)]
|
|
9
9
|
|
|
10
|
-
//
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
// Frontend layout + screens. BASE renders the shared layout; HOME is its default child.
|
|
17
|
-
entrypoints.push(entrypoint(route(BASE, '/', frontend()), handler(MainLayout)))
|
|
18
|
-
entrypoints.push(entrypoint(route(HOME, '/', frontend({ default: true, parent: BASE })), handler(HomeScreen)))
|
|
19
|
-
entrypoints.push(entrypoint(route(web.session, '/session', frontend({ parent: BASE })), handler(SessionScreen)))
|
|
20
|
-
entrypoints.push(entrypoint(route(web.about, '/about', frontend({ parent: BASE })), handler(AboutScreen)))
|
|
10
|
+
// Frontend protocol declarations bind to renderers in the web project.
|
|
11
|
+
entrypoints.push(bindScreen(web.base, handler(MainLayout)))
|
|
12
|
+
entrypoints.push(bindScreen(web.home, handler(HomeScreen)))
|
|
13
|
+
entrypoints.push(bindScreen(web.session, handler(SessionScreen)))
|
|
14
|
+
entrypoints.push(bindScreen(web.about, handler(AboutScreen)))
|
|
21
15
|
|
|
22
16
|
export const appEntrypoints = entrypoints
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { useEffect, useState, type FC } from 'react'
|
|
2
|
-
import type { ClientEntrypoint } from '@owlmeans/client-entrypoint'
|
|
3
2
|
import { useStoreList } from '@owlmeans/client'
|
|
4
3
|
import { session, type SessionItem } from '__APP_SLUG__-common'
|
|
5
4
|
import { SESSION_STATE, useContext } from '../context.js'
|
|
@@ -39,7 +38,7 @@ export const SessionScreen: FC = () => {
|
|
|
39
38
|
// leave the store too, and one write wakes the subscribers once instead of once per record.
|
|
40
39
|
const load = async () => {
|
|
41
40
|
const data = await ctx
|
|
42
|
-
.entrypoint
|
|
41
|
+
.entrypoint(session.list)
|
|
43
42
|
.call({ params: { sid } })
|
|
44
43
|
await store.replace(data ?? [])
|
|
45
44
|
}
|
|
@@ -51,7 +50,7 @@ export const SessionScreen: FC = () => {
|
|
|
51
50
|
setBusy(true)
|
|
52
51
|
try {
|
|
53
52
|
const item = await ctx
|
|
54
|
-
.entrypoint
|
|
53
|
+
.entrypoint(session.add)
|
|
55
54
|
.call({ params: { sid }, body: { text } })
|
|
56
55
|
setText('')
|
|
57
56
|
if (item != null) {
|
|
@@ -64,7 +63,7 @@ export const SessionScreen: FC = () => {
|
|
|
64
63
|
|
|
65
64
|
const remove = async (id: string) => {
|
|
66
65
|
await ctx
|
|
67
|
-
.entrypoint
|
|
66
|
+
.entrypoint(session.remove)
|
|
68
67
|
.call({ params: { sid, id } })
|
|
69
68
|
await store.delete(id)
|
|
70
69
|
}
|