alinea 1.3.1 → 1.4.0-preview.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.
Files changed (65) hide show
  1. package/dist/.init/content/pages/welcome.json +1 -1
  2. package/dist/LICENSES.md +102 -102
  3. package/dist/adapter/next/cms.js +1 -1
  4. package/dist/backend/Handler.js +19 -8
  5. package/dist/backend/api/GithubApi.js +43 -12
  6. package/dist/chunks/{chunk-V4O6S3PC.js → chunk-LDLSN5JK.js} +1 -1
  7. package/dist/cli/Serve.js +1 -1
  8. package/dist/cli/bin.js +1 -1
  9. package/dist/cloud/CloudRemote.js +24 -10
  10. package/dist/core/Graph.js +2 -1
  11. package/dist/core/Outcome.d.ts +2 -1
  12. package/dist/core/Outcome.js +10 -4
  13. package/dist/core/db/EntryIndex.d.ts +9 -3
  14. package/dist/core/db/EntryIndex.js +55 -35
  15. package/dist/core/db/EntryTransaction.d.ts +2 -1
  16. package/dist/core/db/EntryTransaction.js +69 -35
  17. package/dist/core/db/LocalDB.js +11 -3
  18. package/dist/core/db/Mutation.d.ts +6 -1
  19. package/dist/core/db/Operation.d.ts +7 -0
  20. package/dist/core/db/Operation.js +20 -9
  21. package/dist/core/db/WriteableGraph.d.ts +5 -4
  22. package/dist/core/db/WriteableGraph.js +14 -10
  23. package/dist/core/source/FSSource.d.ts +0 -2
  24. package/dist/core/source/FSSource.js +0 -13
  25. package/dist/core/source/GithubSource.d.ts +1 -0
  26. package/dist/core/source/GithubSource.js +11 -11
  27. package/dist/core/source/Tree.js +2 -1
  28. package/dist/dashboard/Routes.d.ts +6 -2
  29. package/dist/dashboard/atoms/DbAtoms.d.ts +1 -1
  30. package/dist/dashboard/atoms/DbAtoms.js +7 -14
  31. package/dist/dashboard/atoms/EntryAtoms.d.ts +2 -0
  32. package/dist/dashboard/atoms/EntryAtoms.js +25 -0
  33. package/dist/dashboard/atoms/EntryEditorAtoms.d.ts +19 -9
  34. package/dist/dashboard/atoms/EntryEditorAtoms.js +42 -34
  35. package/dist/dashboard/boot/DashboardWorker.js +12 -11
  36. package/dist/dashboard/editor/DefaultViews.d.ts +2 -1
  37. package/dist/dashboard/view/EntryEdit.js +3 -3
  38. package/dist/dashboard/view/EntryTree.js +126 -80
  39. package/dist/dashboard/view/Sidebar.js +9 -1
  40. package/dist/dashboard/view/entry/EntryHeader.js +53 -28
  41. package/dist/dashboard/view/entry/NewEntry.js +5 -3
  42. package/dist/field/list/ListField.view.d.ts +1 -1
  43. package/dist/field/list/ListField.view.js +3 -3
  44. package/dist/field/object/ObjectField.d.ts +12 -4
  45. package/dist/index.css +130 -55
  46. package/dist/test/status.test.d.ts +1 -0
  47. package/dist/ui/AppBar.d.ts +1 -1
  48. package/dist/ui/AppBar.js +2 -0
  49. package/dist/ui/Button.d.ts +1 -1
  50. package/dist/ui/Button.js +13 -5
  51. package/dist/ui/icons/IcBaselinePause.d.ts +2 -0
  52. package/dist/ui/icons/IcBaselinePause.js +20 -0
  53. package/dist/ui/icons/IcOutlineArchive.d.ts +2 -0
  54. package/dist/ui/icons/IcOutlineArchive.js +26 -0
  55. package/dist/ui/icons/IcOutlineFolder.d.ts +2 -0
  56. package/dist/ui/icons/IcOutlineFolder.js +26 -0
  57. package/dist/ui/icons/IcRoundNotes.d.ts +0 -1
  58. package/dist/ui/icons/IcRoundNotes.js +1 -3
  59. package/dist/ui/icons/IcTwotoneDescription.d.ts +2 -0
  60. package/dist/ui/icons/IcTwotoneDescription.js +37 -0
  61. package/dist/ui/icons/IcTwotoneFolder.d.ts +2 -0
  62. package/dist/ui/icons/IcTwotoneFolder.js +37 -0
  63. package/dist/ui/icons/IcTwotoneInsertDriveFile.d.ts +2 -0
  64. package/dist/ui/icons/IcTwotoneInsertDriveFile.js +30 -0
  65. package/package.json +1 -1
@@ -1,5 +1,5 @@
1
1
  {
2
- "_id": "2ygHI5LHHVmR2H8kYrePnoHLbcB",
2
+ "_id": "2zK16TfpATzOs6qMMNCmcqMSd5w",
3
3
  "_type": "Page",
4
4
  "_index": "a0",
5
5
  "_seeded": "welcome.json",
package/dist/LICENSES.md CHANGED
@@ -28,6 +28,29 @@ SOFTWARE.
28
28
 
29
29
  ===
30
30
 
31
+ # htmlparser2@9.1.0 (MIT)
32
+
33
+ Copyright 2010, 2011, Chris Winberry <chris@winberry.net>. All rights reserved.
34
+ Permission is hereby granted, free of charge, to any person obtaining a copy
35
+ of this software and associated documentation files (the "Software"), to
36
+ deal in the Software without restriction, including without limitation the
37
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
38
+ sell copies of the Software, and to permit persons to whom the Software is
39
+ furnished to do so, subject to the following conditions:
40
+
41
+ The above copyright notice and this permission notice shall be included in
42
+ all copies or substantial portions of the Software.
43
+
44
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
45
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
46
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
47
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
48
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
49
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
50
+ IN THE SOFTWARE.
51
+
52
+ ===
53
+
31
54
  # react-query@3.39.3 (MIT)
32
55
 
33
56
  MIT License
@@ -55,11 +78,11 @@ SOFTWARE.
55
78
 
56
79
  ===
57
80
 
58
- # lib0@0.2.88 (MIT)
81
+ # @headlessui/react@2.2.0 (MIT)
59
82
 
60
- The MIT License (MIT)
83
+ MIT License
61
84
 
62
- Copyright (c) 2019 Kevin Jahns <kevin.jahns@protonmail.com>.
85
+ Copyright (c) 2020 Tailwind Labs
63
86
 
64
87
  Permission is hereby granted, free of charge, to any person obtaining a copy
65
88
  of this software and associated documentation files (the "Software"), to deal
@@ -79,14 +102,13 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
79
102
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
80
103
  SOFTWARE.
81
104
 
82
-
83
105
  ===
84
106
 
85
- # @headlessui/react@2.2.0 (MIT)
107
+ # lib0@0.2.88 (MIT)
86
108
 
87
- MIT License
109
+ The MIT License (MIT)
88
110
 
89
- Copyright (c) 2020 Tailwind Labs
111
+ Copyright (c) 2019 Kevin Jahns <kevin.jahns@protonmail.com>.
90
112
 
91
113
  Permission is hereby granted, free of charge, to any person obtaining a copy
92
114
  of this software and associated documentation files (the "Software"), to deal
@@ -106,54 +128,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
106
128
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
107
129
  SOFTWARE.
108
130
 
109
- ===
110
-
111
- # htmlparser2@9.1.0 (MIT)
112
-
113
- Copyright 2010, 2011, Chris Winberry <chris@winberry.net>. All rights reserved.
114
- Permission is hereby granted, free of charge, to any person obtaining a copy
115
- of this software and associated documentation files (the "Software"), to
116
- deal in the Software without restriction, including without limitation the
117
- rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
118
- sell copies of the Software, and to permit persons to whom the Software is
119
- furnished to do so, subject to the following conditions:
120
-
121
- The above copyright notice and this permission notice shall be included in
122
- all copies or substantial portions of the Software.
123
-
124
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
125
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
126
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
127
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
128
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
129
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
130
- IN THE SOFTWARE.
131
-
132
- ===
133
-
134
- # @popperjs/core@2.11.8 (MIT)
135
-
136
- The MIT License (MIT)
137
-
138
- Copyright (c) 2019 Federico Zivolo
139
-
140
- Permission is hereby granted, free of charge, to any person obtaining a copy of
141
- this software and associated documentation files (the "Software"), to deal in
142
- the Software without restriction, including without limitation the rights to
143
- use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
144
- the Software, and to permit persons to whom the Software is furnished to do so,
145
- subject to the following conditions:
146
-
147
- The above copyright notice and this permission notice shall be included in all
148
- copies or substantial portions of the Software.
149
-
150
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
151
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
152
- FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
153
- COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
154
- IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
155
- CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
156
-
157
131
 
158
132
  ===
159
133
 
@@ -208,29 +182,40 @@ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
208
182
 
209
183
  ===
210
184
 
211
- # prop-types@15.8.1 (MIT)
185
+ # @headless-tree/core@0.0.15 (MIT)
212
186
 
213
- MIT License
187
+ MIT
214
188
 
215
- Copyright (c) 2013-present, Facebook, Inc.
189
+ ===
216
190
 
217
- Permission is hereby granted, free of charge, to any person obtaining a copy
218
- of this software and associated documentation files (the "Software"), to deal
219
- in the Software without restriction, including without limitation the rights
220
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
221
- copies of the Software, and to permit persons to whom the Software is
222
- furnished to do so, subject to the following conditions:
191
+ # @headless-tree/react@0.0.15 (MIT)
192
+
193
+ MIT
194
+
195
+ ===
196
+
197
+ # @popperjs/core@2.11.8 (MIT)
198
+
199
+ The MIT License (MIT)
200
+
201
+ Copyright (c) 2019 Federico Zivolo
202
+
203
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
204
+ this software and associated documentation files (the "Software"), to deal in
205
+ the Software without restriction, including without limitation the rights to
206
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
207
+ the Software, and to permit persons to whom the Software is furnished to do so,
208
+ subject to the following conditions:
223
209
 
224
210
  The above copyright notice and this permission notice shall be included in all
225
211
  copies or substantial portions of the Software.
226
212
 
227
213
  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
228
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
229
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
230
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
231
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
232
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
233
- SOFTWARE.
214
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
215
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
216
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
217
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
218
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
234
219
 
235
220
 
236
221
  ===
@@ -442,15 +427,30 @@ SOFTWARE.
442
427
 
443
428
  ===
444
429
 
445
- # @headless-tree/react@0.0.15 (MIT)
430
+ # prop-types@15.8.1 (MIT)
446
431
 
447
- MIT
432
+ MIT License
448
433
 
449
- ===
434
+ Copyright (c) 2013-present, Facebook, Inc.
450
435
 
451
- # @headless-tree/core@0.0.15 (MIT)
436
+ Permission is hereby granted, free of charge, to any person obtaining a copy
437
+ of this software and associated documentation files (the "Software"), to deal
438
+ in the Software without restriction, including without limitation the rights
439
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
440
+ copies of the Software, and to permit persons to whom the Software is
441
+ furnished to do so, subject to the following conditions:
442
+
443
+ The above copyright notice and this permission notice shall be included in all
444
+ copies or substantial portions of the Software.
445
+
446
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
447
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
448
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
449
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
450
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
451
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
452
+ SOFTWARE.
452
453
 
453
- MIT
454
454
 
455
455
  ===
456
456
 
@@ -1585,6 +1585,33 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1585
1585
  See the License for the specific language governing permissions and
1586
1586
  limitations under the License.
1587
1587
 
1588
+ ===
1589
+
1590
+ # @tanstack/virtual-core@3.10.6 (MIT)
1591
+
1592
+ MIT License
1593
+
1594
+ Copyright (c) 2021-present Tanner Linsley
1595
+
1596
+ Permission is hereby granted, free of charge, to any person obtaining a copy
1597
+ of this software and associated documentation files (the "Software"), to deal
1598
+ in the Software without restriction, including without limitation the rights
1599
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1600
+ copies of the Software, and to permit persons to whom the Software is
1601
+ furnished to do so, subject to the following conditions:
1602
+
1603
+ The above copyright notice and this permission notice shall be included in all
1604
+ copies or substantial portions of the Software.
1605
+
1606
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1607
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1608
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1609
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1610
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1611
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1612
+ SOFTWARE.
1613
+
1614
+
1588
1615
  ===
1589
1616
 
1590
1617
  # @react-stately/utils@3.10.5 (Apache-2.0)
@@ -1790,30 +1817,3 @@ limitations under the License.
1790
1817
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1791
1818
  See the License for the specific language governing permissions and
1792
1819
  limitations under the License.
1793
-
1794
-
1795
- ===
1796
-
1797
- # @tanstack/virtual-core@3.10.6 (MIT)
1798
-
1799
- MIT License
1800
-
1801
- Copyright (c) 2021-present Tanner Linsley
1802
-
1803
- Permission is hereby granted, free of charge, to any person obtaining a copy
1804
- of this software and associated documentation files (the "Software"), to deal
1805
- in the Software without restriction, including without limitation the rights
1806
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
1807
- copies of the Software, and to permit persons to whom the Software is
1808
- furnished to do so, subject to the following conditions:
1809
-
1810
- The above copyright notice and this permission notice shall be included in all
1811
- copies or substantial portions of the Software.
1812
-
1813
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
1814
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
1815
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
1816
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
1817
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
1818
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1819
- SOFTWARE.
@@ -63,7 +63,7 @@ var NextCMS = class extends CMS {
63
63
  const { PHASE_PRODUCTION_BUILD } = await import("next/constants");
64
64
  const isBuild = process.env.NEXT_PHASE === PHASE_PRODUCTION_BUILD;
65
65
  const { db, previews } = await this.init;
66
- const sync = () => db.syncWith(client);
66
+ const sync = () => db.syncWith(client).catch(console.error);
67
67
  if (!isBuild) {
68
68
  if (preview) {
69
69
  preview = await previews.parse(preview, sync);
@@ -16,6 +16,7 @@ import { JWTPreviews } from "alinea/backend/util/JWTPreviews";
16
16
  import { CloudRemote } from "alinea/cloud/CloudRemote";
17
17
  import { HttpError } from "alinea/core/HttpError";
18
18
  import { getScope } from "alinea/core/Scope";
19
+ import { ShaMismatchError } from "alinea/core/source/ShaMismatchError";
19
20
  import { base64 } from "alinea/core/util/Encoding";
20
21
  import { HandleAction } from "./HandleAction.js";
21
22
  import { createPreviewParser } from "./resolver/ParsePreview.js";
@@ -118,14 +119,24 @@ function createHandler({
118
119
  expectUser();
119
120
  expectJson();
120
121
  const mutations = await body;
121
- const request2 = await local.request(mutations);
122
- const { sha } = await cnx.write(request2);
123
- if (sha === request2.intoSha) {
124
- await local.write(request2);
125
- } else {
122
+ const attempt = async (retry = 0) => {
126
123
  await local.syncWith(cnx);
127
- }
128
- return Response.json({ sha });
124
+ const request2 = await local.request(mutations);
125
+ try {
126
+ let { sha } = await cnx.write(request2);
127
+ if (sha === request2.intoSha) {
128
+ await local.write(request2);
129
+ } else {
130
+ sha = await local.syncWith(cnx);
131
+ }
132
+ return sha;
133
+ } catch (error) {
134
+ if (error instanceof ShaMismatchError && retry < 3)
135
+ return attempt(retry + 1);
136
+ throw error;
137
+ }
138
+ };
139
+ return Response.json({ sha: await attempt() });
129
140
  }
130
141
  if (action === HandleAction.Commit && request.method === "POST") {
131
142
  throw new Error("Mutations expected");
@@ -141,7 +152,7 @@ function createHandler({
141
152
  if (action === HandleAction.Tree && request.method === "GET") {
142
153
  expectJson();
143
154
  const sha = string(url.searchParams.get("sha"));
144
- await periodicSync(cnx);
155
+ await local.syncWith(cnx);
145
156
  const tree = await local.getTreeIfDifferent(sha);
146
157
  return Response.json(tree ?? null);
147
158
  }
@@ -5,6 +5,7 @@ import { HttpError } from "alinea/core/HttpError";
5
5
  import {
6
6
  GithubSource
7
7
  } from "alinea/core/source/GithubSource";
8
+ import { ShaMismatchError } from "alinea/core/source/ShaMismatchError";
8
9
  import { base64, btoa } from "alinea/core/util/Encoding";
9
10
  import { join } from "alinea/core/util/Paths";
10
11
  var GithubApi = class extends GithubSource {
@@ -14,6 +15,10 @@ var GithubApi = class extends GithubSource {
14
15
  this.#options = options;
15
16
  }
16
17
  async write(request) {
18
+ const currentCommit = await getLatestCommitOid(this.#options);
19
+ const currentSha = await this.shaAt(currentCommit);
20
+ if (currentSha !== request.fromSha)
21
+ throw new ShaMismatchError(currentSha, request.fromSha);
17
22
  const { author } = this.#options;
18
23
  let commitMessage = request.description;
19
24
  if (author) {
@@ -21,8 +26,13 @@ var GithubApi = class extends GithubSource {
21
26
 
22
27
  Co-authored-by: ${author.name} <${author.email}>`;
23
28
  }
24
- await applyChangesToRepo(this.#options, request.changes, commitMessage);
25
- return this.getTree().then((tree) => ({ sha: tree.sha }));
29
+ const newCommit = await applyChangesToRepo(
30
+ this.#options,
31
+ currentCommit,
32
+ request.changes,
33
+ commitMessage
34
+ );
35
+ return { sha: await this.shaAt(newCommit) };
26
36
  }
27
37
  async revisions(file) {
28
38
  return getFileCommitHistory(this.#options, file);
@@ -51,6 +61,13 @@ function graphQL(query, variables, token) {
51
61
  }).then(async (response) => {
52
62
  if (response.ok) return response.json();
53
63
  throw new HttpError(response.status, await response.text());
64
+ }).then((result) => {
65
+ if (Array.isArray(result.errors) && result.errors.length > 0) {
66
+ const message = result.errors.map((e) => e.message).join("; ");
67
+ console.trace(result.errors);
68
+ throw new Error(message);
69
+ }
70
+ return result;
54
71
  });
55
72
  }
56
73
  async function getFileCommitHistory({ owner, repo, branch, authToken, rootDir }, file) {
@@ -104,7 +121,7 @@ async function getFileContentAtCommit({ owner, repo, authToken, rootDir }, file,
104
121
  );
105
122
  return result.data.repository.object?.text;
106
123
  }
107
- async function applyChangesToRepo(options, changes, commitMessage) {
124
+ async function applyChangesToRepo(options, expectedHeadOid, changes, commitMessage) {
108
125
  const { additions, deletions } = await processChanges(options, changes);
109
126
  const { owner, repo, branch, authToken } = options;
110
127
  return graphQL(
@@ -121,18 +138,32 @@ async function applyChangesToRepo(options, changes, commitMessage) {
121
138
  repositoryNameWithOwner: `${owner}/${repo}`,
122
139
  branchName: branch
123
140
  },
124
- message: {
125
- headline: commitMessage
126
- },
127
- fileChanges: {
128
- additions,
129
- deletions
130
- },
131
- expectedHeadOid: await getLatestCommitOid(options)
141
+ message: { headline: commitMessage },
142
+ fileChanges: { additions, deletions },
143
+ expectedHeadOid
132
144
  }
133
145
  },
134
146
  authToken
135
- ).then((result) => result.data.createCommitOnBranch.commit.oid);
147
+ ).then((result) => {
148
+ const commitId = result.data.createCommitOnBranch.commit.oid;
149
+ return commitId;
150
+ }).catch((error) => {
151
+ if (error instanceof Error) {
152
+ const mismatchMessage = /is at ([a-z0-9]+) but expected ([a-z0-9]+)/;
153
+ const match = error.message.match(mismatchMessage);
154
+ if (match) {
155
+ const [_, actual, expected] = match;
156
+ throw new ShaMismatchError(actual, expected);
157
+ }
158
+ const expectedMessage = /Expected branch to point to "([a-z0-9]+)"/;
159
+ const expectedMatch = error.message.match(expectedMessage);
160
+ if (expectedMatch) {
161
+ const actualSha = expectedMatch[1];
162
+ throw new ShaMismatchError(actualSha, expectedHeadOid);
163
+ }
164
+ }
165
+ throw error;
166
+ });
136
167
  }
137
168
  async function processChanges({ rootDir, contentDir }, changes) {
138
169
  const additions = Array();
@@ -2,7 +2,7 @@
2
2
  var package_default = {
3
3
  bin: "./dist/cli.js",
4
4
  name: "alinea",
5
- version: "1.3.1",
5
+ version: "1.4.0-preview.1",
6
6
  description: "Headless git-based CMS",
7
7
  repository: {
8
8
  type: "git",
package/dist/cli/Serve.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  package_default
3
- } from "../chunks/chunk-V4O6S3PC.js";
3
+ } from "../chunks/chunk-LDLSN5JK.js";
4
4
  import "../chunks/chunk-NZLE2WMY.js";
5
5
 
6
6
  // src/cli/Serve.ts
package/dist/cli/bin.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  package_default
3
- } from "../chunks/chunk-V4O6S3PC.js";
3
+ } from "../chunks/chunk-LDLSN5JK.js";
4
4
  import "../chunks/chunk-NZLE2WMY.js";
5
5
 
6
6
  // node_modules/mri/lib/index.mjs
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  package_default
3
- } from "../chunks/chunk-V4O6S3PC.js";
3
+ } from "../chunks/chunk-LDLSN5JK.js";
4
4
  import {
5
5
  PLazy
6
6
  } from "../chunks/chunk-IKINPSS5.js";
@@ -18,6 +18,7 @@ import {
18
18
  import { HttpError } from "alinea/core/HttpError";
19
19
  import { Outcome, outcome } from "alinea/core/Outcome";
20
20
  import { Workspace } from "alinea/core/Workspace";
21
+ import { ShaMismatchError } from "alinea/core/source/ShaMismatchError";
21
22
  import { ReadonlyTree } from "alinea/core/source/Tree";
22
23
  import { base64 } from "alinea/core/util/Encoding";
23
24
  import { verify } from "alinea/core/util/JWT";
@@ -100,7 +101,14 @@ var CloudRemote = class {
100
101
  })
101
102
  })
102
103
  )
103
- );
104
+ ).catch((error) => {
105
+ if (error instanceof HttpError && error.code === 409) {
106
+ const actual = "actualSha" in error && error.actualSha;
107
+ const expected = "expectedSha" in error && error.expectedSha;
108
+ if (actual && expected) throw new ShaMismatchError(actual, expected);
109
+ }
110
+ throw error;
111
+ });
104
112
  }
105
113
  async authenticate(request) {
106
114
  const ctx = this.#context;
@@ -325,15 +333,21 @@ function json(init = {}) {
325
333
  headers.set("accept", "application/json");
326
334
  return { ...init, headers };
327
335
  }
328
- async function failOnHttpError(res) {
329
- if (res.status >= 400) throw new HttpError(res.status, await res.text());
330
- return res;
336
+ async function failOnHttpError(response) {
337
+ if (!response.ok) throw new HttpError(response.status, await response.text());
338
+ return response;
331
339
  }
332
- function parseJson(res) {
333
- return res.json();
334
- }
335
- function parseOutcome(res) {
336
- return res.then(failOnHttpError).then(parseJson).then(Outcome.fromJSON).then(Outcome.unpack);
340
+ async function parseOutcome(expected) {
341
+ const response = await expected;
342
+ const contentType = response.headers.get("content-type");
343
+ const isJson = contentType?.includes("application/json");
344
+ if (!response.ok && !isJson) {
345
+ const message = await response.text();
346
+ throw new HttpError(response.status, message);
347
+ }
348
+ const output = await response.json();
349
+ const outcome2 = Outcome.fromJSON(output, response.status);
350
+ return Outcome.unpack(outcome2);
337
351
  }
338
352
  export {
339
353
  COOKIE_NAME,
@@ -9,8 +9,9 @@ var Graph = class {
9
9
  return this.resolve({ ...query, first: true });
10
10
  }
11
11
  async get(query) {
12
+ const error = globalThis.Bun ? new Error("Entry not found") : void 0;
12
13
  const result = await this.resolve({ ...query, get: true });
13
- if (!result) throw new Error("Entry not found");
14
+ if (!result) throw error ?? new Error("Entry not found");
14
15
  return result;
15
16
  }
16
17
  count(query) {
@@ -1,3 +1,4 @@
1
+ import { type ErrorCode } from './HttpError.js';
1
2
  type ErrorObject = {
2
3
  stack?: string;
3
4
  message?: string;
@@ -21,7 +22,7 @@ export declare namespace outcome {
21
22
  }
22
23
  export type Outcome<T = void> = Outcome.OutcomeImpl<T> & Pair<T>;
23
24
  export declare namespace Outcome {
24
- export function fromJSON<T>(json: OutcomeJSON<T>): Outcome<T>;
25
+ export function fromJSON<T>(json: OutcomeJSON<T>, status?: ErrorCode): Outcome<T>;
25
26
  export function unpack<T>(outcome: Outcome<T>): T;
26
27
  export function isOutcome(value: any): value is Outcome;
27
28
  export function Success<T>(data: T): Outcome<T>;
@@ -2,6 +2,7 @@ import "../chunks/chunk-NZLE2WMY.js";
2
2
 
3
3
  // src/core/Outcome.ts
4
4
  import { HttpError } from "./HttpError.js";
5
+ import { assign } from "./util/Objects.js";
5
6
  function outcome(run) {
6
7
  try {
7
8
  if (typeof run === "function") {
@@ -37,16 +38,21 @@ function isPromiseLike(value) {
37
38
  })(outcome || (outcome = {}));
38
39
  var Outcome;
39
40
  ((Outcome2) => {
40
- function fromJSON(json) {
41
+ function fromJSON(json, status) {
41
42
  if (json.success) return Success(json.data);
42
- const error = new HttpError(json.error.status, json.error.message);
43
- error.stack = json.error.stack;
43
+ const error = new HttpError(
44
+ json.error.status ?? status ?? 500,
45
+ json.error.message ?? "Unknown error"
46
+ );
47
+ assign(error, json.error);
48
+ if (json.error.stack) error.stack = json.error.stack;
44
49
  return Failure(error);
45
50
  }
46
51
  Outcome2.fromJSON = fromJSON;
47
52
  function unpack(outcome2) {
48
53
  if (outcome2.isSuccess()) return outcome2.value;
49
- throw outcome2.error;
54
+ if (outcome2.isFailure()) throw outcome2.error;
55
+ throw new Error("Outcome is neither success nor failure");
50
56
  }
51
57
  Outcome2.unpack = unpack;
52
58
  function isOutcome(value) {
@@ -1,6 +1,5 @@
1
1
  import { Config } from 'alinea/core/Config';
2
- import type { Entry } from 'alinea/core/Entry';
3
- import type { EntryStatus } from 'alinea/core/Entry';
2
+ import type { Entry, EntryStatus } from 'alinea/core/Entry';
4
3
  import type { ChangesBatch } from '../source/Change.js';
5
4
  import { type Source } from '../source/Source.js';
6
5
  import { ReadonlyTree } from '../source/Tree.js';
@@ -31,12 +30,19 @@ export declare class EntryIndex extends EventTarget {
31
30
  indexChanges(batch: ChangesBatch): Promise<string>;
32
31
  updateSearch(entry: Entry): Promise<void>;
33
32
  }
33
+ declare class Versions extends Map<EntryStatus, Entry> {
34
+ inheritedStatus: EntryStatus | undefined;
35
+ setInherited(parentStatus: EntryStatus | undefined): void;
36
+ get active(): Entry | undefined;
37
+ get main(): Entry | undefined;
38
+ versions(): Generator<Entry>;
39
+ }
34
40
  declare class EntryNode {
35
41
  #private;
36
42
  id: string;
37
43
  type: string;
38
44
  byFile: Map<string, Entry>;
39
- locales: Map<string | null, Map<EntryStatus, Entry>>;
45
+ locales: Map<string | null, Versions>;
40
46
  constructor(config: Config, from: Entry);
41
47
  get index(): string;
42
48
  get parentId(): string | null;