@uniweb/api 0.2.13 → 0.3.1

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 CHANGED
@@ -1,25 +1,25 @@
1
1
  # @uniweb/api
2
2
 
3
- The client a foundation uses to talk to **its site's own backend** — sign-in, the
3
+ The client a foundation uses to talk to **its site's `api` service** — sign-in, the
4
4
  site's members, and the content they create.
5
5
 
6
6
  You import it the way you import `@uniweb/kit`. It is bundled into your foundation,
7
- tree-shaken, and **inert on a site that has no backend**: nothing throws, no request
7
+ tree-shaken, and **inert on a site that has no `api` service**: nothing throws, no request
8
8
  leaves, and your components render the version of themselves that does not need one.
9
9
 
10
10
  ```bash
11
11
  npm install @uniweb/api
12
12
  ```
13
13
 
14
- ## Is there a backend?
14
+ ## Does the site have the service?
15
15
 
16
16
  Ask before you draw. This is a synchronous read of the site's own configuration, not
17
17
  a probe — there is nothing to await.
18
18
 
19
19
  ```jsx
20
- import { isEnabled } from '@uniweb/api'
20
+ import { isApiEnabled } from '@uniweb/kit'
21
21
 
22
- if (!isEnabled(website)) return <StaticVersion />
22
+ if (!isApiEnabled()) return <StaticVersion />
23
23
  ```
24
24
 
25
25
  ⛔ **And when the answer is no, draw nothing** — not a disabled button, and not an
@@ -62,8 +62,8 @@ const { status, records, matched, hasMore } = useRecords({ schema: '@/session' }
62
62
  ```
63
63
 
64
64
  ⭐ **`absent` and an empty `ready` are different answers.** `absent` means there is no
65
- live source — no backend, or nobody signed in — so render your site's own content.
66
- `ready` with `records: []` means the backend answered and there is nothing there.
65
+ live source — no `api` service, or nobody signed in — so render your site's own content.
66
+ `ready` with `records: []` means the service answered and there is nothing there.
67
67
  Showing "nothing yet" for the first case tells a visitor their content is missing
68
68
  when it is simply not being asked for.
69
69
 
@@ -100,13 +100,13 @@ Three things it does for you, and one it deliberately does not:
100
100
 
101
101
  ⚠️ `update` replaces the item's data whole. Spread what you are not editing.
102
102
 
103
- ## A backend on your machine
103
+ ## The service on your machine
104
104
 
105
- Building against a live backend is slow and puts a shared database behind your
105
+ Building against a live service is slow and puts a shared database behind your
106
106
  experiments. Name a local one in `site.yml`:
107
107
 
108
108
  ```yaml
109
- api: /_api # where the backend answers — the same in production
109
+ api: /_api # where the service answers — the same in production
110
110
  $devApi: ./mock/api.js # what answers it locally; never published
111
111
  ```
112
112
 
@@ -137,7 +137,7 @@ npx uniweb-api-mock --port 8787
137
137
  ```
138
138
 
139
139
  ⛔ **The mock is a fixture of what this package expects, not a model of any real
140
- backend.** Behaviour it happens to have is evidence about the mock and nothing else.
140
+ server.** Behaviour it happens to have is evidence about the mock and nothing else.
141
141
 
142
142
  ## Outside React
143
143
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@uniweb/api",
3
- "version": "0.2.13",
3
+ "version": "0.3.1",
4
4
  "description": "The client for a Uniweb site's own backend — session, records, entities — imported by a foundation the way it imports @uniweb/kit.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -34,7 +34,7 @@
34
34
  "node": ">=20.19"
35
35
  },
36
36
  "dependencies": {
37
- "@uniweb/core": "^0.24.2"
37
+ "@uniweb/core": "^0.24.4"
38
38
  },
39
39
  "peerDependencies": {
40
40
  "react": "^19.0.0"
package/src/client.js CHANGED
@@ -31,8 +31,8 @@ export const CONTRACT = 1
31
31
  /**
32
32
  * Where the site's backend is, if it has one.
33
33
  *
34
- * `resolveService` answers with the site's own declaration first (`api:` in
35
- * `site.yml`), then the host's (`config.services.api`), and `null` when neither
34
+ * `resolveService` answers with the host's offer first (`config.services.api`),
35
+ * then the site's own declaration (`api:` in `site.yml`), and `null` when neither
36
36
  * names an address. Absence is the ordinary state of a site with no backend,
37
37
  * not an error.
38
38
  *
@@ -44,16 +44,34 @@ export function resolveBase(website) {
44
44
  }
45
45
 
46
46
  /**
47
- * Does this site have a backend the package can talk to?
47
+ * Does this site have an app backend — the `api` service?
48
48
  *
49
49
  * The question to ask before drawing a sign-in affordance or any control only a
50
50
  * backend can answer. False means: draw nothing, or the static alternative the
51
51
  * site already carries.
52
52
  *
53
- * @param {object} website
53
+ * ⭐ **The website argument is OPTIONAL and defaults to the active one**, so this
54
+ * is the same call as `@uniweb/kit`'s `isApiEnabled()` — one predicate per
55
+ * service, no arguments, the website resolved for you. Pass one explicitly only
56
+ * when you already hold it, or are working outside a render.
57
+ *
58
+ * ⛔ **THE DEFAULT IS NOT A CONVENIENCE, IT CLOSES A TRAP.** For one commit this
59
+ * took a REQUIRED website while every doc and template showed the no-argument
60
+ * spelling — so `import { isApiEnabled } from '@uniweb/api'` followed by
61
+ * `isApiEnabled()` resolved `undefined`, returned `false` forever, and drew no
62
+ * sign-in UI on a site that had a backend. Silent, and indistinguishable from a
63
+ * site with no backend: exactly the invisible absence this predicate exists to
64
+ * prevent. Caught in review the same day; pinned by `tests/enabled.test.js`.
65
+ *
66
+ * ⛔ **Renamed from `isEnabled` (2026-09-10).** The old name said nothing about
67
+ * its subject and collided with three unrelated `isEnabled`s in the framework —
68
+ * including the field `useSearch()` returns, which made `uniweb doctor` read a
69
+ * search control as gated when it was gated on this instead.
70
+ *
71
+ * @param {object} [website] - defaults to the active website
54
72
  * @returns {boolean}
55
73
  */
56
- export function isEnabled(website) {
74
+ export function isApiEnabled(website = getUniweb()?.activeWebsite ?? null) {
57
75
  return resolveBase(website) !== null
58
76
  }
59
77
 
package/src/index.js CHANGED
@@ -13,7 +13,7 @@
13
13
  export {
14
14
  SERVICE_NAME,
15
15
  resolveBase,
16
- isEnabled,
16
+ isApiEnabled,
17
17
  probeSession,
18
18
  signIn,
19
19
  completeChallenge,