@proveanything/smartlinks 2.0.57 → 2.0.60

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.
@@ -0,0 +1,91 @@
1
+ # Websites: server-rendered on the SmartLinks site runtime
2
+
3
+ A website built on SmartLinks is an app whose public side is a **server-rendered site** at its own
4
+ address: an automatic `*.smartlinks.host` name, a chosen name, or the business's own domain. Every
5
+ page arrives as finished HTML, so search engines, AI crawlers and link previews see the real
6
+ content, and visitors see it before any JavaScript runs.
7
+
8
+ ## How a request is served
9
+
10
+ ```
11
+ visitor / crawler / agent
12
+ └─► SmartLinks site router (edge)
13
+ ├─ /robots.txt, /sitemap.xml, /llms.txt made by the platform (site-seo.md)
14
+ ├─ a file in your build (has an extension) served from the build, cached at the edge
15
+ └─ anything else your site's server renders it
16
+ • runs in an isolated worker, close to the SmartLinks API
17
+ • may call the SmartLinks API and the hosts you declare, nothing else
18
+ • request header x-sl-site says which site it is (SL.site.fromRequest)
19
+ ```
20
+
21
+ The router also adds the canonical or noindex header, the security headers, and
22
+ `window.__SMARTLINKS_SITE__` to every HTML page (read in the browser with `SL.site.current()` or
23
+ `SL.readContext()`).
24
+
25
+ ## The build
26
+
27
+ The website template (TanStack Start) produces this; you don't write it by hand.
28
+
29
+ ```
30
+ dist/
31
+ ├── index.html? / assets/… the client build (hashed files: cached for a year)
32
+ ├── sitemap-paths.txt your pages, "<path> [Title]" per line (site-seo.md)
33
+ ├── _server/ the server bundle: one ES module entry + its chunks
34
+ │ └── index.mjs exports default { fetch(request, env, ctx) } (WinterTC)
35
+ └── app.manifest.json
36
+ ```
37
+
38
+ Manifest:
39
+
40
+ ```jsonc
41
+ "site": {
42
+ "server": {
43
+ "main": "_server/index.mjs", // the server entry, inside the build
44
+ "compatibilityFlags": ["nodejs_compat"] // allowed: nodejs_compat, nodejs_compat_v2, nodejs_als
45
+ },
46
+ "network": ["api.example-weather.com"] // other hosts the server may call (optional)
47
+ }
48
+ ```
49
+
50
+ On publish, the server folder becomes the site's server for that channel. Promote copies the same
51
+ bytes. `_server/` is never served to visitors.
52
+
53
+ ## The server's rules
54
+
55
+ - **Which site:** `const site = SL.site.fromRequest(request)` gives `{ host, collectionId, appId,
56
+ channel, canonicalHost }`. One build serves every site it's installed on, so always take the
57
+ collection from here, never from a constant.
58
+ - **Data:** call the SmartLinks API with the SDK as you would in the browser. The server reads what
59
+ an anonymous visitor could read on that site, and only that collection. It holds no keys and no
60
+ signed-in user.
61
+ - **Writes** (contact forms, entries, sign-ups) go to your app's **server functions**
62
+ (server-functions.md), called from the browser as today. Their capabilities, secrets and limits
63
+ apply.
64
+ - **Other hosts:** only those in `site.network`. Anything else is refused (`403 Blocked`).
65
+ - **Limits per request:** a CPU-time budget and a cap on outgoing calls. A page that needs more is
66
+ doing work that belongs in a server function or a scheduled job.
67
+ - **No secrets** in the server bundle and no Node built-ins beyond `nodejs_compat`.
68
+
69
+ ## Caching
70
+
71
+ The router keeps a rendered page at the edge when your response says it may:
72
+
73
+ | Your response | At the edge |
74
+ |---|---|
75
+ | `Cache-Control: public, s-maxage=300` (the template's default for pages) | kept up to 5 minutes |
76
+ | `private`, `no-store`, `no-cache`, or a `Set-Cookie` | never kept |
77
+ | no `Cache-Control` | never kept |
78
+
79
+ Cached pages are keyed by the release and the collection's **content generation**: when products,
80
+ public app records, app settings or the collection change, the generation moves and every page of
81
+ the collection's sites re-renders on its next visit (within about 30 seconds). Publishing a release
82
+ does the same. Tracking parameters (`utm_*`, `gclid`, `fbclid`…) don't create separate entries.
83
+
84
+ Keep pages the same for every visitor. Anything personal (a signed-in owner's products, a basket)
85
+ renders in the browser after load.
86
+
87
+ ## Locally
88
+
89
+ `npm run dev` runs the site with your dev collection (`.env`: `VITE_SL_COLLECTION_ID`), because
90
+ there's no router to say which site it is: `SL.site.fromRequest()` is null, so fall back to it.
91
+ Forge's preview runs the same server code the site runtime does.
package/openapi.yaml CHANGED
@@ -19766,7 +19766,9 @@ components:
19766
19766
  type: string
19767
19767
  sample:
19768
19768
  type: string
19769
- transform:
19769
+ shape:
19770
+ type: string
19771
+ serialize:
19770
19772
  type: string
19771
19773
  send:
19772
19774
  type: string
@@ -19778,6 +19780,11 @@ components:
19778
19780
  $ref: "#/components/schemas/ConnectorPanel"
19779
19781
  aiGuide:
19780
19782
  type: string
19783
+ recordId:
19784
+ type: string
19785
+ limits:
19786
+ type: object
19787
+ additionalProperties: true
19781
19788
  required:
19782
19789
  - provider
19783
19790
  - directions
@@ -19860,7 +19867,7 @@ components:
19860
19867
  type: string
19861
19868
  required:
19862
19869
  - records
19863
- ConnectorTransformInput:
19870
+ ConnectorShapeInput:
19864
19871
  type: object
19865
19872
  properties:
19866
19873
  installation:
@@ -19870,15 +19877,40 @@ components:
19870
19877
  items:
19871
19878
  type: object
19872
19879
  additionalProperties: true
19873
- mapping:
19880
+ required:
19881
+ - installation
19882
+ - records
19883
+ ConnectorShapeResult:
19884
+ type: object
19885
+ properties:
19886
+ documents:
19874
19887
  type: array
19875
19888
  items:
19876
- $ref: "#/components/schemas/FieldMapping"
19889
+ type: object
19890
+ additionalProperties: true
19891
+ skipped:
19892
+ type: array
19893
+ items:
19894
+ type: object
19895
+ additionalProperties: true
19896
+ required:
19897
+ - documents
19898
+ ConnectorSerializeInput:
19899
+ type: object
19900
+ properties:
19901
+ installation:
19902
+ $ref: "#/components/schemas/ConnectorInstallation"
19903
+ documents:
19904
+ type: array
19905
+ items:
19906
+ type: object
19907
+ additionalProperties: true
19908
+ eventType:
19909
+ type: string
19877
19910
  required:
19878
19911
  - installation
19879
- - records
19880
- - mapping
19881
- ConnectorTransformResult:
19912
+ - documents
19913
+ ConnectorSerializeResult:
19882
19914
  type: object
19883
19915
  properties:
19884
19916
  payloads:
@@ -19906,12 +19938,26 @@ components:
19906
19938
  type: object
19907
19939
  properties:
19908
19940
  results:
19909
- type: array
19910
- items:
19911
- type: object
19912
- additionalProperties: true
19941
+ type: object
19942
+ additionalProperties: true
19943
+ index:
19944
+ type: number
19945
+ ok:
19946
+ type: boolean
19947
+ status:
19948
+ type: number
19949
+ error:
19950
+ type: string
19951
+ externalId:
19952
+ type: string
19953
+ retryable:
19954
+ type: boolean
19955
+ retryAfterSeconds:
19956
+ type: number
19913
19957
  required:
19914
19958
  - results
19959
+ - index
19960
+ - ok
19915
19961
  ConnectorFetchInput:
19916
19962
  type: object
19917
19963
  properties:
@@ -26251,6 +26297,12 @@ components:
26251
26297
  type: string
26252
26298
  totalSynced:
26253
26299
  type: number
26300
+ circuitOpenedAt:
26301
+ type: string
26302
+ circuitProbeAt:
26303
+ type: string
26304
+ circuitReason:
26305
+ type: string
26254
26306
  required:
26255
26307
  - id
26256
26308
  - orgId
@@ -26267,6 +26319,47 @@ components:
26267
26319
  - createdBy
26268
26320
  - createdAt
26269
26321
  - updatedAt
26322
+ FailedRecord:
26323
+ type: object
26324
+ properties:
26325
+ id:
26326
+ type: string
26327
+ entityId:
26328
+ type: string
26329
+ externalId:
26330
+ type: string
26331
+ status:
26332
+ type: string
26333
+ enum:
26334
+ - failed
26335
+ - dead
26336
+ attempts:
26337
+ type: number
26338
+ nextAttemptAt:
26339
+ type: string
26340
+ lastError:
26341
+ type: string
26342
+ updatedAt:
26343
+ type: string
26344
+ required:
26345
+ - id
26346
+ - status
26347
+ - attempts
26348
+ FailedRecordList:
26349
+ type: object
26350
+ properties:
26351
+ direction:
26352
+ $ref: "#/components/schemas/FlowDirection"
26353
+ items:
26354
+ type: array
26355
+ items:
26356
+ $ref: "#/components/schemas/FailedRecord"
26357
+ nextCursor:
26358
+ type: string
26359
+ required:
26360
+ - direction
26361
+ - items
26362
+ - nextCursor
26270
26363
  CreateFlowInput:
26271
26364
  type: object
26272
26365
  properties:
@@ -26338,6 +26431,8 @@ components:
26338
26431
  type: number
26339
26432
  skipped:
26340
26433
  type: number
26434
+ held:
26435
+ type: number
26341
26436
  status:
26342
26437
  $ref: "#/components/schemas/RunStatus"
26343
26438
  runId:
@@ -26734,7 +26829,8 @@ components:
26734
26829
  - testConnection
26735
26830
  - describeTarget
26736
26831
  - sample
26737
- - transform
26832
+ - shape
26833
+ - serialize
26738
26834
  RunTrigger:
26739
26835
  type: string
26740
26836
  enum:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proveanything/smartlinks",
3
- "version": "2.0.57",
3
+ "version": "2.0.60",
4
4
  "description": "Official JavaScript/TypeScript SDK for the Smartlinks API",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",