@shivaedev/work-board 0.17.0 → 0.18.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 (304) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +27 -25
  3. package/assets/react.css +1 -1
  4. package/assets/react.js +37 -36
  5. package/dist/browser/responses/cardContext.d.ts +8 -1
  6. package/dist/browser/responses/cardContext.d.ts.map +1 -1
  7. package/dist/browser/responses/cardContext.js +12 -7
  8. package/dist/browser/responses/cardContext.js.map +1 -1
  9. package/dist/browser/views/now.d.ts +5 -0
  10. package/dist/browser/views/now.d.ts.map +1 -1
  11. package/dist/browser/views/now.js +38 -2
  12. package/dist/browser/views/now.js.map +1 -1
  13. package/dist/browser/views/schema.d.ts +11 -0
  14. package/dist/browser/views/schema.d.ts.map +1 -1
  15. package/dist/browser/views/schema.js +1 -0
  16. package/dist/browser/views/schema.js.map +1 -1
  17. package/dist/client/document/View.js +1 -1
  18. package/dist/client/document/View.js.map +1 -1
  19. package/dist/client/formStatus.d.ts +2 -2
  20. package/dist/client/formStatus.d.ts.map +1 -1
  21. package/dist/client/formStatus.js +2 -2
  22. package/dist/client/formStatus.js.map +1 -1
  23. package/dist/client/react/AnswerContext.d.ts.map +1 -1
  24. package/dist/client/react/AnswerContext.js +5 -2
  25. package/dist/client/react/AnswerContext.js.map +1 -1
  26. package/dist/client/react/AnswerForm.d.ts.map +1 -1
  27. package/dist/client/react/AnswerForm.js +6 -2
  28. package/dist/client/react/AnswerForm.js.map +1 -1
  29. package/dist/client/react/AnswerMarkdown.d.ts +6 -0
  30. package/dist/client/react/AnswerMarkdown.d.ts.map +1 -0
  31. package/dist/client/react/AnswerMarkdown.js +7 -0
  32. package/dist/client/react/AnswerMarkdown.js.map +1 -0
  33. package/dist/client/react/AnswerMore.d.ts.map +1 -1
  34. package/dist/client/react/AnswerMore.js +2 -1
  35. package/dist/client/react/AnswerMore.js.map +1 -1
  36. package/dist/client/react/AnswerPanel.d.ts.map +1 -1
  37. package/dist/client/react/AnswerPanel.js +3 -2
  38. package/dist/client/react/AnswerPanel.js.map +1 -1
  39. package/dist/client/react/AnswerPrompts.d.ts.map +1 -1
  40. package/dist/client/react/AnswerPrompts.js +16 -10
  41. package/dist/client/react/AnswerPrompts.js.map +1 -1
  42. package/dist/client/react/BoardShell.js +2 -2
  43. package/dist/client/react/BoardShell.js.map +1 -1
  44. package/dist/client/react/DocumentMain.d.ts.map +1 -1
  45. package/dist/client/react/DocumentMain.js +2 -2
  46. package/dist/client/react/DocumentMain.js.map +1 -1
  47. package/dist/client/react/FleetMain.js +1 -1
  48. package/dist/client/react/FleetMain.js.map +1 -1
  49. package/dist/client/react/FormField.js +1 -1
  50. package/dist/client/react/FormField.js.map +1 -1
  51. package/dist/client/react/GoalPage.js +2 -2
  52. package/dist/client/react/GoalPage.js.map +1 -1
  53. package/dist/client/react/GoalProgressHeader.js +2 -2
  54. package/dist/client/react/GoalProgressHeader.js.map +1 -1
  55. package/dist/client/react/Header.d.ts.map +1 -1
  56. package/dist/client/react/Header.js +3 -2
  57. package/dist/client/react/Header.js.map +1 -1
  58. package/dist/client/react/LibraryContents.js +1 -1
  59. package/dist/client/react/LibraryContents.js.map +1 -1
  60. package/dist/client/react/LibraryMain.d.ts.map +1 -1
  61. package/dist/client/react/LibraryMain.js +1 -1
  62. package/dist/client/react/LibraryMain.js.map +1 -1
  63. package/dist/client/react/LibraryPage.js +2 -2
  64. package/dist/client/react/LibraryPage.js.map +1 -1
  65. package/dist/client/react/LiveControls.js +1 -1
  66. package/dist/client/react/LiveControls.js.map +1 -1
  67. package/dist/client/react/ProjectionMain.d.ts.map +1 -1
  68. package/dist/client/react/ProjectionMain.js +1 -1
  69. package/dist/client/react/ProjectionMain.js.map +1 -1
  70. package/dist/client/react/PromptOption.d.ts.map +1 -1
  71. package/dist/client/react/PromptOption.js +7 -5
  72. package/dist/client/react/PromptOption.js.map +1 -1
  73. package/dist/client/react/ReadingHistory.js +1 -1
  74. package/dist/client/react/ReadingHistory.js.map +1 -1
  75. package/dist/client/react/RemainingMain.d.ts.map +1 -1
  76. package/dist/client/react/RemainingMain.js +1 -1
  77. package/dist/client/react/RemainingMain.js.map +1 -1
  78. package/dist/client/react/ResponseHistory.d.ts.map +1 -1
  79. package/dist/client/react/ResponseHistory.js +11 -5
  80. package/dist/client/react/ResponseHistory.js.map +1 -1
  81. package/dist/client/react/SearchPalette.js +1 -1
  82. package/dist/client/react/SearchPalette.js.map +1 -1
  83. package/dist/client/react/Sidebar.d.ts.map +1 -1
  84. package/dist/client/react/Sidebar.js +9 -2
  85. package/dist/client/react/Sidebar.js.map +1 -1
  86. package/dist/client/react/SystemFleetLane.d.ts.map +1 -1
  87. package/dist/client/react/SystemFleetLane.js +2 -1
  88. package/dist/client/react/SystemFleetLane.js.map +1 -1
  89. package/dist/client/react/SystemHealth.d.ts +2 -1
  90. package/dist/client/react/SystemHealth.d.ts.map +1 -1
  91. package/dist/client/react/SystemHealth.js +3 -2
  92. package/dist/client/react/SystemHealth.js.map +1 -1
  93. package/dist/client/react/SystemMain.d.ts.map +1 -1
  94. package/dist/client/react/SystemMain.js +6 -2
  95. package/dist/client/react/SystemMain.js.map +1 -1
  96. package/dist/client/react/SystemPage.d.ts +2 -1
  97. package/dist/client/react/SystemPage.d.ts.map +1 -1
  98. package/dist/client/react/SystemPage.js +2 -2
  99. package/dist/client/react/SystemPage.js.map +1 -1
  100. package/dist/client/react/TodayNeeds.d.ts +5 -0
  101. package/dist/client/react/TodayNeeds.d.ts.map +1 -1
  102. package/dist/client/react/TodayNeeds.js +6 -3
  103. package/dist/client/react/TodayNeeds.js.map +1 -1
  104. package/dist/client/react/TodayOptionButton.d.ts +14 -0
  105. package/dist/client/react/TodayOptionButton.d.ts.map +1 -0
  106. package/dist/client/react/TodayOptionButton.js +10 -0
  107. package/dist/client/react/TodayOptionButton.js.map +1 -0
  108. package/dist/client/react/TodayOptions.d.ts.map +1 -1
  109. package/dist/client/react/TodayOptions.js +18 -14
  110. package/dist/client/react/TodayOptions.js.map +1 -1
  111. package/dist/client/react/TodayPage.d.ts.map +1 -1
  112. package/dist/client/react/TodayPage.js +20 -5
  113. package/dist/client/react/TodayPage.js.map +1 -1
  114. package/dist/client/react/WorkCard.d.ts.map +1 -1
  115. package/dist/client/react/WorkCard.js +7 -2
  116. package/dist/client/react/WorkCard.js.map +1 -1
  117. package/dist/client/react/WorkLane.d.ts.map +1 -1
  118. package/dist/client/react/WorkLane.js +1 -1
  119. package/dist/client/react/WorkLane.js.map +1 -1
  120. package/dist/client/react/WorkNow.js +1 -1
  121. package/dist/client/react/WorkNow.js.map +1 -1
  122. package/dist/client/react/activeRead.js +1 -1
  123. package/dist/client/react/activeRead.js.map +1 -1
  124. package/dist/client/react/destinationName.d.ts +2 -0
  125. package/dist/client/react/destinationName.d.ts.map +1 -0
  126. package/dist/client/react/destinationName.js +4 -0
  127. package/dist/client/react/destinationName.js.map +1 -0
  128. package/dist/client/react/loadBoardPage.d.ts.map +1 -1
  129. package/dist/client/react/loadBoardPage.js +2 -2
  130. package/dist/client/react/loadBoardPage.js.map +1 -1
  131. package/dist/client/react/loadProjection.d.ts +135 -135
  132. package/dist/client/react/loadProjection.d.ts.map +1 -1
  133. package/dist/client/react/loadProjection.js +2 -2
  134. package/dist/client/react/loadProjection.js.map +1 -1
  135. package/dist/client/react/loadRemaining.d.ts +184 -184
  136. package/dist/client/react/loadRemaining.d.ts.map +1 -1
  137. package/dist/client/react/loadRemaining.js +2 -2
  138. package/dist/client/react/loadRemaining.js.map +1 -1
  139. package/dist/client/react/pageQueries.js +1 -1
  140. package/dist/client/react/pageQueries.js.map +1 -1
  141. package/dist/client/react/resolvedDocumentFailure.d.ts.map +1 -0
  142. package/dist/client/react/resolvedDocumentFailure.js.map +1 -0
  143. package/dist/client/react/routeQuery.d.ts.map +1 -0
  144. package/dist/client/react/routeQuery.js.map +1 -0
  145. package/dist/client/react/useHandoffForm.js +1 -1
  146. package/dist/client/react/useHandoffForm.js.map +1 -1
  147. package/dist/client/react/useProjectionData.d.ts +1 -1
  148. package/dist/client/react/useProjectionData.js +1 -1
  149. package/dist/client/react/useProjectionData.js.map +1 -1
  150. package/dist/client/react/useResponseForm.d.ts.map +1 -1
  151. package/dist/client/react/useResponseForm.js +3 -3
  152. package/dist/client/react/useResponseForm.js.map +1 -1
  153. package/dist/client/responses/summary.d.ts +1 -0
  154. package/dist/client/responses/summary.d.ts.map +1 -1
  155. package/dist/client/responses/summary.js +12 -1
  156. package/dist/client/responses/summary.js.map +1 -1
  157. package/dist/diagnostics/source.js +1 -1
  158. package/dist/diagnostics/source.js.map +1 -1
  159. package/dist/rpc/contract.d.ts +1951 -1918
  160. package/dist/rpc/contract.d.ts.map +1 -1
  161. package/dist/server/Responses.js +2 -2
  162. package/dist/server/Responses.js.map +1 -1
  163. package/dist/server/attention/inbox.d.ts +13 -2
  164. package/dist/server/attention/inbox.d.ts.map +1 -1
  165. package/dist/server/attention/inbox.js +44 -27
  166. package/dist/server/attention/inbox.js.map +1 -1
  167. package/dist/server/attention/managedRequestReceipt.d.ts +10 -0
  168. package/dist/server/attention/managedRequestReceipt.d.ts.map +1 -1
  169. package/dist/server/attention/managedRequestReceipt.js +29 -10
  170. package/dist/server/attention/managedRequestReceipt.js.map +1 -1
  171. package/dist/server/attention/projection.d.ts.map +1 -1
  172. package/dist/server/attention/projection.js +2 -1
  173. package/dist/server/attention/projection.js.map +1 -1
  174. package/dist/server/attention/requestInbox.d.ts +3 -3
  175. package/dist/server/attention/requestInbox.js +2 -2
  176. package/dist/server/attention/requestInbox.js.map +1 -1
  177. package/dist/server/attention/requests.d.ts +1 -0
  178. package/dist/server/attention/requests.d.ts.map +1 -1
  179. package/dist/server/attention/requests.js +7 -3
  180. package/dist/server/attention/requests.js.map +1 -1
  181. package/dist/server/board.js +1 -1
  182. package/dist/server/board.js.map +1 -1
  183. package/dist/server/document/answerBody.d.ts.map +1 -1
  184. package/dist/server/document/answerBody.js +9 -1
  185. package/dist/server/document/answerBody.js.map +1 -1
  186. package/dist/server/document/reviewedWork.d.ts +3 -0
  187. package/dist/server/document/reviewedWork.d.ts.map +1 -0
  188. package/dist/server/document/reviewedWork.js +23 -0
  189. package/dist/server/document/reviewedWork.js.map +1 -0
  190. package/dist/server/files/changes.d.ts.map +1 -1
  191. package/dist/server/files/changes.js +1 -1
  192. package/dist/server/files/changes.js.map +1 -1
  193. package/dist/server/files/watchDirectories.d.ts +1 -1
  194. package/dist/server/files/watchDirectories.d.ts.map +1 -1
  195. package/dist/server/files/watchDirectories.js +71 -12
  196. package/dist/server/files/watchDirectories.js.map +1 -1
  197. package/dist/server/handoffs/Service.js +2 -2
  198. package/dist/server/handoffs/Service.js.map +1 -1
  199. package/dist/server/handoffs/source.js +1 -1
  200. package/dist/server/handoffs/source.js.map +1 -1
  201. package/dist/server/http/boardRoutes.js +1 -1
  202. package/dist/server/http/boardRoutes.js.map +1 -1
  203. package/dist/server/mcp/client.d.ts +11 -0
  204. package/dist/server/mcp/client.d.ts.map +1 -1
  205. package/dist/server/mcp/queries.d.ts +2851 -2818
  206. package/dist/server/mcp/queries.d.ts.map +1 -1
  207. package/dist/server/packageInfo.d.ts +1 -1
  208. package/dist/server/packageInfo.js +1 -1
  209. package/dist/server/render/Highlighter.js +1 -1
  210. package/dist/server/render/Highlighter.js.map +1 -1
  211. package/dist/server/responses/locate.js +1 -1
  212. package/dist/server/responses/locate.js.map +1 -1
  213. package/dist/server/rpc/handlers.js +2 -2
  214. package/dist/server/rpc/handlers.js.map +1 -1
  215. package/dist/server/serve.js +1 -1
  216. package/dist/server/serve.js.map +1 -1
  217. package/dist/server/views/projectionQueries.d.ts +11 -0
  218. package/dist/server/views/projectionQueries.d.ts.map +1 -1
  219. package/dist/server/workspace.js +1 -1
  220. package/dist/server/workspace.js.map +1 -1
  221. package/docs/delivery/README.md +2 -2
  222. package/package.json +18 -362
  223. package/src/browser/responses/cardContext.ts +13 -7
  224. package/src/browser/views/now.ts +42 -2
  225. package/src/browser/views/schema.ts +1 -0
  226. package/src/client/document/View.ts +1 -1
  227. package/src/client/formStatus.ts +3 -3
  228. package/src/client/react/AnswerContext.tsx +9 -4
  229. package/src/client/react/AnswerForm.tsx +25 -6
  230. package/src/client/react/AnswerMarkdown.tsx +15 -0
  231. package/src/client/react/AnswerMore.tsx +58 -46
  232. package/src/client/react/AnswerPanel.tsx +14 -8
  233. package/src/client/react/AnswerPrompts.tsx +33 -18
  234. package/src/client/react/BoardShell.tsx +2 -2
  235. package/src/client/react/DocumentMain.tsx +2 -2
  236. package/src/client/react/FleetMain.tsx +1 -1
  237. package/src/client/react/FormField.tsx +1 -1
  238. package/src/client/react/GoalPage.tsx +2 -2
  239. package/src/client/react/GoalProgressHeader.tsx +2 -2
  240. package/src/client/react/Header.tsx +3 -2
  241. package/src/client/react/LibraryContents.tsx +1 -1
  242. package/src/client/react/LibraryMain.tsx +1 -1
  243. package/src/client/react/LibraryPage.tsx +2 -2
  244. package/src/client/react/LiveControls.tsx +1 -1
  245. package/src/client/react/ProjectionMain.tsx +1 -1
  246. package/src/client/react/PromptOption.tsx +39 -24
  247. package/src/client/react/ReadingHistory.tsx +1 -1
  248. package/src/client/react/RemainingMain.tsx +1 -1
  249. package/src/client/react/ResponseHistory.tsx +53 -14
  250. package/src/client/react/SearchPalette.tsx +1 -1
  251. package/src/client/react/Sidebar.tsx +10 -2
  252. package/src/client/react/SystemFleetLane.tsx +2 -1
  253. package/src/client/react/SystemHealth.tsx +24 -4
  254. package/src/client/react/SystemMain.tsx +6 -2
  255. package/src/client/react/SystemPage.tsx +8 -2
  256. package/src/client/react/TodayNeeds.tsx +21 -6
  257. package/src/client/react/TodayOptionButton.tsx +35 -0
  258. package/src/client/react/TodayOptions.tsx +42 -33
  259. package/src/client/react/TodayPage.tsx +36 -7
  260. package/src/client/react/WorkCard.tsx +16 -8
  261. package/src/client/react/WorkLane.tsx +8 -2
  262. package/src/client/react/WorkNow.tsx +1 -1
  263. package/src/client/react/activeRead.ts +1 -1
  264. package/src/client/react/destinationName.ts +3 -0
  265. package/src/client/react/entry.css +0 -6
  266. package/src/client/react/loadBoardPage.ts +2 -2
  267. package/src/client/react/loadProjection.ts +2 -2
  268. package/src/client/react/loadRemaining.ts +2 -2
  269. package/src/client/react/pageQueries.ts +1 -1
  270. package/src/client/react/useHandoffForm.ts +1 -1
  271. package/src/client/react/useProjectionData.ts +1 -1
  272. package/src/client/react/useResponseForm.ts +5 -3
  273. package/src/client/responses/summary.ts +13 -1
  274. package/src/diagnostics/source.ts +1 -1
  275. package/src/server/Responses.ts +2 -2
  276. package/src/server/attention/inbox.ts +51 -27
  277. package/src/server/attention/managedRequestReceipt.ts +41 -10
  278. package/src/server/attention/projection.ts +5 -2
  279. package/src/server/attention/requestInbox.ts +2 -2
  280. package/src/server/attention/requests.ts +7 -2
  281. package/src/server/board.ts +1 -1
  282. package/src/server/document/answerBody.ts +10 -1
  283. package/src/server/document/reviewedWork.ts +24 -0
  284. package/src/server/files/changes.ts +1 -0
  285. package/src/server/files/watchDirectories.ts +90 -27
  286. package/src/server/handoffs/Service.ts +2 -2
  287. package/src/server/handoffs/source.ts +1 -1
  288. package/src/server/http/boardRoutes.ts +1 -1
  289. package/src/server/packageInfo.ts +1 -1
  290. package/src/server/render/Highlighter.ts +1 -1
  291. package/src/server/responses/locate.ts +1 -1
  292. package/src/server/rpc/handlers.ts +2 -2
  293. package/src/server/serve.ts +1 -1
  294. package/src/server/workspace.ts +1 -1
  295. package/dist/client/page/resolvedDocumentFailure.d.ts.map +0 -1
  296. package/dist/client/page/resolvedDocumentFailure.js.map +0 -1
  297. package/dist/client/page/routeQuery.d.ts.map +0 -1
  298. package/dist/client/page/routeQuery.js.map +0 -1
  299. /package/dist/client/{page → react}/resolvedDocumentFailure.d.ts +0 -0
  300. /package/dist/client/{page → react}/resolvedDocumentFailure.js +0 -0
  301. /package/dist/client/{page → react}/routeQuery.d.ts +0 -0
  302. /package/dist/client/{page → react}/routeQuery.js +0 -0
  303. /package/src/client/{page → react}/resolvedDocumentFailure.ts +0 -0
  304. /package/src/client/{page → react}/routeQuery.ts +0 -0
@@ -0,0 +1,24 @@
1
+ import { metadataParse } from "#server/metadata/parse.ts";
2
+
3
+ export const REVIEWED_WORK_HEADING = "## Reviewed Board work";
4
+
5
+ export function reviewedWork(source: string): string | undefined {
6
+ const parsed = metadataParse(source);
7
+ if (parsed.raw === undefined || parsed.diagnostics.length > 0) {
8
+ return undefined;
9
+ }
10
+ const heading = /^\s*#[ \t]+(?<title>.+?)[ \t]*(?:\r?\n|$)/u.exec(parsed.body);
11
+ const title = heading?.groups?.title ?? parsed.fields.id;
12
+ const body = parsed.body.slice(heading?.[0].length ?? 0).trim();
13
+ const criteria = parsed.fields.criteria ?? [];
14
+ return [
15
+ [title && `**${title}**`, parsed.fields.id && `\`${parsed.fields.id}\``].filter(Boolean).join(" · "),
16
+ criteria.length > 0 ? `Criteria:\n\n${criteria.map((criterion) => `- ${criterion.text}`).join("\n")}` : "",
17
+ body
18
+ .split("\n")
19
+ .map((line) => (line.trim() ? `> ${line}` : ">"))
20
+ .join("\n"),
21
+ ]
22
+ .filter((block) => block.length > 0 && block !== ">")
23
+ .join("\n\n");
24
+ }
@@ -76,6 +76,7 @@ export const watchChanges = Effect.fn("WorkBoard.watchChanges")(function* (root:
76
76
  setWatching,
77
77
  (paths) => Effect.andThen(invalidate(paths), Effect.andThen(finishPending, publish({ _tag: "Changed", paths }))),
78
78
  observed,
79
+ finishPending,
79
80
  );
80
81
  yield* attempt.pipe(
81
82
  Effect.sandbox,
@@ -5,6 +5,38 @@ import { isMarkdown, scanMarkdown } from "./list.ts";
5
5
 
6
6
  const SETTLE = "100 millis";
7
7
 
8
+ type WatchRoots = readonly { readonly real: string; readonly relative: string }[];
9
+
10
+ function changedFiles(previous: ReadonlyMap<string, number>, next: ReadonlyMap<string, number>) {
11
+ return [...new Set([...previous.keys(), ...next.keys()])].filter((file) => previous.get(file) !== next.get(file));
12
+ }
13
+
14
+ function sameRoots(previous: WatchRoots, next: WatchRoots): boolean {
15
+ const known = new Map(previous.map((folder) => [folder.relative, folder.real]));
16
+ return previous.length === next.length && next.every((folder) => known.get(folder.relative) === folder.real);
17
+ }
18
+
19
+ function directoryEvent(relative: string, info: Option.Option<FileSystem.File.Info>, roots: WatchRoots, contents: ReadonlyMap<string, number>) {
20
+ if (Option.isSome(info)) {
21
+ return info.value.type === "Directory";
22
+ }
23
+ return (
24
+ roots.some((folder) => folder.relative === relative || folder.relative.startsWith(`${relative}/`))
25
+ || [...contents.keys()].some((file) => file.startsWith(`${relative}/`))
26
+ );
27
+ }
28
+
29
+ function recordFile(contents: Map<string, number>, relative: string, info: Option.Option<FileSystem.File.Info>) {
30
+ if (!isMarkdown(relative)) {
31
+ return;
32
+ }
33
+ if (Option.isSome(info) && info.value.type === "File") {
34
+ contents.set(relative, Option.match(info.value.mtime, { onNone: () => 0, onSome: (date) => date.getTime() }));
35
+ } else {
36
+ contents.delete(relative);
37
+ }
38
+ }
39
+
8
40
  export const watchDirectories = Effect.fn("WorkBoard.watchDirectories")(function* (
9
41
  root: string,
10
42
  realRoot: string,
@@ -12,12 +44,14 @@ export const watchDirectories = Effect.fn("WorkBoard.watchDirectories")(function
12
44
  setWatching: (watching: boolean) => Effect.Effect<unknown>,
13
45
  publish: (paths: readonly string[]) => Effect.Effect<unknown>,
14
46
  observed: Effect.Effect<void> = Effect.void,
47
+ settled: Effect.Effect<unknown> = Effect.void,
15
48
  ) {
16
49
  const fs = yield* FileSystem.FileSystem;
17
50
  const path = yield* Path.Path;
18
51
  const cycle = Effect.scoped(
19
52
  Effect.gen(function* () {
20
- const { roots } = yield* scanMarkdown(root, realRoot);
53
+ const { files, roots } = yield* scanMarkdown(root, realRoot);
54
+ let contents = new Map(files.map((file) => [file.path, file.modified]));
21
55
  const topology = yield* Deferred.make<void>();
22
56
  // Node's recursive watcher can miss replacement of directory symlinks.
23
57
  const parents = yield* Effect.forEach(
@@ -34,37 +68,66 @@ export const watchDirectories = Effect.fn("WorkBoard.watchDirectories")(function
34
68
  }),
35
69
  ),
36
70
  );
71
+ // A removed root can be reported without any descendant file events.
72
+ streams.push(
73
+ fs.watch(path.dirname(realRoot)).pipe(
74
+ Stream.filter((event) => event._tag === "Remove" && path.resolve(path.dirname(realRoot), event.path) === realRoot),
75
+ Stream.map(() => ""),
76
+ ),
77
+ );
37
78
  const pending = new Set<string>();
79
+ let rescan = false;
80
+ const queueRescan = Effect.gen(function* () {
81
+ if (rescan) {
82
+ return;
83
+ }
84
+ rescan = true;
85
+ yield* stale;
86
+ });
87
+ const changedPath = Effect.fn("WorkBoard.changedPath")(function* (relative: string) {
88
+ const relevant = isMarkdown(relative) || attachmentType(relative) !== undefined;
89
+ if (relevant) {
90
+ yield* observed;
91
+ }
92
+ const info = yield* Effect.option(fs.stat(path.join(root, relative)));
93
+ if (directoryEvent(relative, info, roots, contents)) {
94
+ if (!relevant) {
95
+ yield* observed;
96
+ }
97
+ yield* queueRescan;
98
+ return true;
99
+ }
100
+ recordFile(contents, relative, info);
101
+ if (relevant) {
102
+ pending.add(relative);
103
+ }
104
+ return relevant;
105
+ });
106
+ const flush = Effect.gen(function* () {
107
+ if (rescan) {
108
+ rescan = false;
109
+ const next = yield* scanMarkdown(root, realRoot);
110
+ if (!sameRoots(roots, next.roots)) {
111
+ return yield* Deferred.succeed(topology, undefined);
112
+ }
113
+ const snapshot = new Map(next.files.map((file) => [file.path, file.modified]));
114
+ for (const file of changedFiles(contents, snapshot)) {
115
+ pending.add(file);
116
+ }
117
+ contents = snapshot;
118
+ }
119
+ const paths = [...pending];
120
+ pending.clear();
121
+ return yield* paths.length > 0 ? publish(paths) : settled;
122
+ });
38
123
  const watch = Stream.mergeAll(streams, { concurrency: "unbounded" }).pipe(
39
- Stream.filter(
40
- (relative) => !relative.split("/").some((segment) => segment === ".board.sock.starting" || /^\.s[A-Za-z0-9]{6}$/u.test(segment)),
41
- ),
42
- Stream.tap((relative) => (isMarkdown(relative) || attachmentType(relative) !== undefined ? observed : Effect.void)),
43
- Stream.tap((relative) =>
44
- Effect.gen(function* () {
45
- const info = yield* Effect.option(fs.stat(path.join(root, relative)));
46
- const removedLink = roots.some((folder) => folder.relative === relative || folder.relative.startsWith(`${relative}/`));
47
- if (Option.match(info, { onNone: () => removedLink, onSome: (value) => value.type === "Directory" })) {
48
- yield* stale;
49
- yield* Effect.forkScoped(Effect.delay(Deferred.succeed(topology, undefined), SETTLE));
50
- }
51
- }),
52
- ),
53
- Stream.filter((relative) => isMarkdown(relative) || attachmentType(relative) !== undefined),
54
- Stream.tap((relative) =>
55
- Effect.sync(() => {
56
- pending.add(relative);
57
- }),
124
+ Stream.filter((relative) =>
125
+ relative.split("/").every((segment) => segment === "." || (!segment.startsWith(".") && segment !== "node_modules")),
58
126
  ),
127
+ Stream.filterEffect(changedPath),
59
128
  Stream.interruptWhen(Deferred.await(topology)),
60
129
  Stream.debounce(SETTLE),
61
- Stream.runForEach(() =>
62
- Effect.suspend(() => {
63
- const paths = [...pending];
64
- pending.clear();
65
- return publish(paths);
66
- }),
67
- ),
130
+ Stream.runForEach(() => flush),
68
131
  Effect.andThen(
69
132
  Effect.flatMap(Deferred.isDone(topology), (changed) =>
70
133
  changed
@@ -1,8 +1,8 @@
1
1
  import { join } from "node:path";
2
2
  import { Clock, Effect, FileSystem, Path, Semaphore } from "effect";
3
- import { defineService } from "@shivaedev/effect-service/define-service.ts";
3
+ import { defineService } from "@shivaedev/effect-service/defineService.ts";
4
4
  import { Conflict, Forbidden, NotFound, PreconditionFailed, ServiceUnavailable } from "@shivaedev/platform/errors/taxonomy.ts";
5
- import { rpcBoundary } from "@shivaedev/platform/rpc-server/boundary.ts";
5
+ import { rpcBoundary } from "@shivaedev/platform/server/rpc-server/boundary.ts";
6
6
  import type { Handoff, HandoffInput } from "#browser/handoffs/schema.ts";
7
7
  import { markdownPath } from "#server/files/markdownPath.ts";
8
8
  import { handoffFrom, handoffMarkdown, handoffPrompt, matchesHandoff } from "#server/handoffs/records.ts";
@@ -1,6 +1,6 @@
1
1
  import { Effect, type FileSystem } from "effect";
2
2
  import { BadRequest, NotFound, PreconditionFailed, ServiceUnavailable } from "@shivaedev/platform/errors/taxonomy.ts";
3
- import { rpcBoundary } from "@shivaedev/platform/rpc-server/boundary.ts";
3
+ import { rpcBoundary } from "@shivaedev/platform/server/rpc-server/boundary.ts";
4
4
  import type { HandoffPreview } from "#browser/handoffs/schema.ts";
5
5
  import type { ResponseRejection } from "#rpc/rejections.ts";
6
6
  import { markdownPath } from "#server/files/markdownPath.ts";
@@ -1,6 +1,6 @@
1
1
  import { Effect, type FileSystem, type Path, type Scope } from "effect";
2
2
  import { HttpRouter, type HttpServerRequest, HttpServerResponse } from "effect/http";
3
- import { loopbackOnly } from "@shivaedev/platform/rpc-server/local.ts";
3
+ import { loopbackOnly } from "@shivaedev/platform/server/rpc-server/local.ts";
4
4
  import type { Diagnostics } from "#diagnostics/source.ts";
5
5
  import { responseUrl } from "#responses/url.ts";
6
6
  import type { BoardOptions } from "#server/board.ts";
@@ -1,2 +1,2 @@
1
1
  export const NAME = "work-board";
2
- export const VERSION = "0.17.0";
2
+ export const VERSION = "0.18.0";
@@ -1,6 +1,6 @@
1
1
  import { Effect } from "effect";
2
2
  import { createHighlighter } from "shiki";
3
- import { defineService } from "@shivaedev/effect-service/define-service.ts";
3
+ import { defineService } from "@shivaedev/effect-service/defineService.ts";
4
4
  import { codeBlocks, THEMES } from "#render/code.ts";
5
5
  import { RenderFailed } from "#render/Failed.ts";
6
6
 
@@ -1,6 +1,6 @@
1
1
  import { Effect, type FileSystem } from "effect";
2
2
  import { BadRequest, NotFound, PreconditionFailed, ServiceUnavailable } from "@shivaedev/platform/errors/taxonomy.ts";
3
- import { rpcBoundary } from "@shivaedev/platform/rpc-server/boundary.ts";
3
+ import { rpcBoundary } from "@shivaedev/platform/server/rpc-server/boundary.ts";
4
4
  import type { QuestionPreview } from "#browser/responses/schema.ts";
5
5
  import type { ResponseRejection } from "#rpc/rejections.ts";
6
6
  import { currentDocument } from "#server/currentDocument.ts";
@@ -1,7 +1,7 @@
1
1
  import { Effect, Layer, Ref, Stream } from "effect";
2
2
  import { InternalServerError, ServiceUnavailable } from "@shivaedev/platform/errors/taxonomy.ts";
3
- import { rpcBoundary } from "@shivaedev/platform/rpc-server/boundary.ts";
4
- import { requestTracingLayer } from "@shivaedev/platform/rpc-server/tracing.ts";
3
+ import { rpcBoundary } from "@shivaedev/platform/server/rpc-server/boundary.ts";
4
+ import { requestTracingLayer } from "@shivaedev/platform/server/rpc-server/tracing.ts";
5
5
  import { workRpcs } from "#rpc/contract.ts";
6
6
  import { DocumentRejection, ResponseRejection } from "#rpc/rejections.ts";
7
7
  import { HandoffsService } from "#server/handoffs/Service.ts";
@@ -1,7 +1,7 @@
1
1
  import { Context, Deferred, Effect, Layer, Path } from "effect";
2
2
  import { HttpServer } from "effect/http";
3
3
  import * as NetAddress from "effect/net/NetAddress";
4
- import { appHost } from "@shivaedev/platform/appHost.ts";
4
+ import { appHost } from "@shivaedev/platform/server/appHost.ts";
5
5
  import { workRpcs } from "#rpc/contract.ts";
6
6
  import type { Server } from "#rpc/Server.ts";
7
7
  import { boardRuntime } from "#server/boardRuntime.ts";
@@ -1,5 +1,5 @@
1
1
  import { Context, Effect, FileSystem, Path, type PlatformError } from "effect";
2
- import { defineService } from "@shivaedev/effect-service/define-service.ts";
2
+ import { defineService } from "@shivaedev/effect-service/defineService.ts";
3
3
  import type { Document } from "#browser/document/schema.ts";
4
4
  import { readDocument } from "#server/document/read.ts";
5
5
  import type { Changes } from "#server/files/changes.ts";
@@ -1 +0,0 @@
1
- {"version":3,"file":"resolvedDocumentFailure.d.ts","sourceRoot":"","sources":["../../../src/client/page/resolvedDocumentFailure.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAqB,MAAM,QAAQ,CAAC;AAElD,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,OAAO,CAG5E"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"resolvedDocumentFailure.js","sourceRoot":"","sources":["../../../src/client/page/resolvedDocumentFailure.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AAElD,MAAM,UAAU,uBAAuB,CAAC,KAA2B;IAClE,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC;IAClE,OAAO,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;AACvF,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"routeQuery.d.ts","sourceRoot":"","sources":["../../../src/client/page/routeQuery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAEvD,UAAU,OAAO;IAChB,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC,CAAC;CACnE;AAED,eAAO,MAAM,iBAAiB;IAAK,UAAU;CAAU,CAAC;AAExD,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6TAEtD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE;IAAE,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC,CAAA;CAAE;;;;;;;;;;;;+HAE9G"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"routeQuery.js","sourceRoot":"","sources":["../../../src/client/page/routeQuery.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;AAExD,MAAM,UAAU,aAAa,CAAC,GAAY,EAAE,GAAW;IACtD,OAAO,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,EAAE,iBAAiB,CAAC,CAAC;AACvD,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAA+E;IAC9G,OAAO,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,EAAE,iBAAiB,CAAC,CAAC;AACjE,CAAC"}
File without changes
File without changes
File without changes