@notionhq/custom-blocks-dev-shell 0.1.11 → 0.1.13

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,2 @@
1
+ /*! tailwindcss v4.2.4 | MIT License | https://tailwindcss.com */
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000}}}@layer theme{:root,:host{--font-sans:-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-black:#000;--color-white:#fff;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--leading-relaxed:1.625;--radius-lg:.5rem;--radius-xl:.75rem;--radius-2xl:1rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-ink:#32302c;--color-ink-muted:#6b6b68;--color-ink-faint:#9b9a97;--color-ink-fainter:#b3b3b0;--color-nav-ink:#2c2c2b;--color-paper:#fbfbfa;--color-hairline:#e6e5e3;--color-ui-hover:#3b14000d;--color-panel:#42230308;--color-canvas-dark:#191919;--color-pill:#0000000d;--color-pill-dark:#ffffff0e;--color-dark-ink:#ffffffcf;--color-dark-ink-muted:#ffffff75;--color-sidebar:#f7f7f5;--color-sidebar-active:#00000008;--color-sidebar-ink:#5f5e59;--color-sidebar-ink-strong:#1d1b16;--color-sidebar-ink-muted:#7d7a75;--color-hairline-soft:#f0efed;--color-toggle:#e9e9e7;--color-accent:#2383e2;--color-mismatch-ink:#a33}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}:root{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{inset:calc(var(--spacing) * 0)}.start{inset-inline-start:var(--spacing)}.end{inset-inline-end:var(--spacing)}.top-0{top:calc(var(--spacing) * 0)}.top-1\/2{top:50%}.top-full{top:100%}.right-0{right:calc(var(--spacing) * 0)}.right-1\.5{right:calc(var(--spacing) * 1.5)}.bottom-full{bottom:100%}.left-0{left:calc(var(--spacing) * 0)}.z-50{z-index:50}.row-1{grid-row:1}.row-2{grid-row:2}.mx-auto{margin-inline:auto}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.table{display:table}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-5{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.size-6{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.size-7{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-9{height:calc(var(--spacing) * 9)}.h-100{height:calc(var(--spacing) * 100)}.h-\[30px\]{height:30px}.h-\[38px\]{height:38px}.h-screen{height:100vh}.max-h-\[85vh\]{max-height:85vh}.min-h-0{min-height:calc(var(--spacing) * 0)}.w-70{width:calc(var(--spacing) * 70)}.w-\[172px\]{width:172px}.w-full{width:100%}.max-w-190{max-width:calc(var(--spacing) * 190)}.max-w-\[560px\]{max-width:560px}.max-w-\[720px\]{max-width:720px}.max-w-\[960px\]{max-width:960px}.max-w-full{max-width:100%}.min-w-0{min-width:calc(var(--spacing) * 0)}.min-w-40{min-width:calc(var(--spacing) * 40)}.flex-1{flex:1}.flex-none{flex:none}.shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.cursor-pointer{cursor:pointer}.resize{resize:both}.list-disc{list-style-type:disc}.appearance-none{appearance:none}.flex-col{flex-direction:column}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-px{gap:1px}.self-start{align-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-\[4px\]{border-radius:4px}.rounded-\[6px\]{border-radius:6px}.rounded-\[10px\]{border-radius:10px}.rounded-\[12px\]{border-radius:12px}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-hairline{border-color:var(--color-hairline)}.border-hairline-soft{border-color:var(--color-hairline-soft)}.bg-accent{background-color:var(--color-accent)}.bg-black\/40{background-color:#0006}@supports (color:color-mix(in lab, red, red)){.bg-black\/40{background-color:color-mix(in oklab, var(--color-black) 40%, transparent)}}.bg-canvas-dark{background-color:var(--color-canvas-dark)}.bg-panel{background-color:var(--color-panel)}.bg-paper{background-color:var(--color-paper)}.bg-pill{background-color:var(--color-pill)}.bg-pill-dark{background-color:var(--color-pill-dark)}.bg-sidebar{background-color:var(--color-sidebar)}.bg-sidebar-active{background-color:var(--color-sidebar-active)}.bg-toggle{background-color:var(--color-toggle)}.bg-ui-hover{background-color:var(--color-ui-hover)}.bg-white{background-color:var(--color-white)}.p-1{padding:calc(var(--spacing) * 1)}.p-2{padding:calc(var(--spacing) * 2)}.p-4{padding:calc(var(--spacing) * 4)}.p-6{padding:calc(var(--spacing) * 6)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.px-10{padding-inline:calc(var(--spacing) * 10)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-10{padding-block:calc(var(--spacing) * 10)}.pt-10{padding-top:calc(var(--spacing) * 10)}.pt-24{padding-top:calc(var(--spacing) * 24)}.pr-1{padding-right:calc(var(--spacing) * 1)}.pr-1\.5{padding-right:calc(var(--spacing) * 1.5)}.pr-6{padding-right:calc(var(--spacing) * 6)}.pb-1{padding-bottom:calc(var(--spacing) * 1)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-6{padding-bottom:calc(var(--spacing) * 6)}.pl-0\.5{padding-left:calc(var(--spacing) * .5)}.pl-2{padding-left:calc(var(--spacing) * 2)}.pl-3{padding-left:calc(var(--spacing) * 3)}.pl-5{padding-left:calc(var(--spacing) * 5)}.text-center{text-align:center}.text-left{text-align:left}.align-top{vertical-align:top}.font-mono{font-family:var(--font-mono)}.text-body{letter-spacing:-.154px;font-size:14px;line-height:20px}.text-caption{font-size:12px;line-height:16px}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[11px\]{font-size:11px}.text-\[13px\]{font-size:13px}.text-\[17px\]{font-size:17px}.text-\[32px\]{font-size:32px}.text-\[40px\]{font-size:40px}.leading-4{--tw-leading:calc(var(--spacing) * 4);line-height:calc(var(--spacing) * 4)}.leading-10{--tw-leading:calc(var(--spacing) * 10);line-height:calc(var(--spacing) * 10)}.leading-\[1\.2\]{--tw-leading:1.2;line-height:1.2}.leading-\[22px\]{--tw-leading:22px;line-height:22px}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-\[-0\.442px\]{--tw-tracking:-.442px;letter-spacing:-.442px}.tracking-\[-1\.55px\]{--tw-tracking:-1.55px;letter-spacing:-1.55px}.whitespace-nowrap{white-space:nowrap}.text-dark-ink{color:var(--color-dark-ink)}.text-dark-ink-muted{color:var(--color-dark-ink-muted)}.text-ink{color:var(--color-ink)}.text-ink-faint{color:var(--color-ink-faint)}.text-ink-fainter{color:var(--color-ink-fainter)}.text-ink-muted{color:var(--color-ink-muted)}.text-mismatch-ink{color:var(--color-mismatch-ink)}.text-nav-ink{color:var(--color-nav-ink)}.text-sidebar-ink{color:var(--color-sidebar-ink)}.text-sidebar-ink-muted{color:var(--color-sidebar-ink-muted)}.text-sidebar-ink-strong{color:var(--color-sidebar-ink-strong)}.text-white{color:var(--color-white)}.opacity-0{opacity:0}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_4px_12px_rgb\(0_0_0\/10\%\)\]{--tw-shadow:0 4px 12px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-\[0_12px_40px_rgb\(0_0_0\/25\%\)\]{--tw-shadow:0 12px 40px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}@media (hover:hover){.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}}.last\:border-b-0:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}@media (hover:hover){.hover\:bg-sidebar-active:hover{background-color:var(--color-sidebar-active)}.hover\:bg-ui-hover:hover{background-color:var(--color-ui-hover)}.hover\:opacity-90:hover{opacity:.9}}.focus-visible\:opacity-100:focus-visible{opacity:1}.disabled\:cursor-default:disabled{cursor:default}.disabled\:bg-toggle:disabled{background-color:var(--color-toggle)}.disabled\:text-ink-faint:disabled{color:var(--color-ink-faint)}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}
package/dist/index.html CHANGED
@@ -4,8 +4,8 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>Workers local shell</title>
7
- <script type="module" crossorigin src="/assets/index-BWWoeYho.js"></script>
8
- <link rel="stylesheet" crossorigin href="/assets/index-D7A1CDPg.css">
7
+ <script type="module" crossorigin src="/assets/index-3yGtnx4Z.js"></script>
8
+ <link rel="stylesheet" crossorigin href="/assets/index-D-pOONlZ.css">
9
9
  </head>
10
10
  <body>
11
11
  <div id="root"></div>
package/dist-cli/main.js CHANGED
@@ -14,6 +14,7 @@ import { BLOCK_BASE_PORT, buildBlockRegistry, SHELL_PORT, writeBlockViteConfig,
14
14
  import { runConvert } from "./convert.js";
15
15
  import { readDataSources } from "./data-sources.js";
16
16
  import { materializeWorkerSchemaDataSources } from "./materialize.js";
17
+ import { copyPrebuiltDataSources } from "./prebuilt.js";
17
18
  import { serveUi } from "./serve-ui.js";
18
19
  import { blockCapabilities, findWorkerDir, generateWorkerManifest, } from "./worker-manifest.js";
19
20
  const __dirname = dirname(fileURLToPath(import.meta.url));
@@ -127,8 +128,9 @@ async function main() {
127
128
  // Materialize schema-only files for the worker's declared sources, then
128
129
  // load the directory. Files are validated before injection; a malformed
129
130
  // file fails spin-up with the problem named.
130
- materializeWorkerSchemaDataSources(manifest, resolve(workerDir, "src/data"));
131
- const dataSources = readDataSources(resolve(workerDir, "src/data"));
131
+ const dataDir = resolve(workerDir, "src/data");
132
+ materializeWorkerSchemaDataSources(manifest, dataDir);
133
+ const dataSources = readDataSources(dataDir);
132
134
  console.log(dataSources.length > 0
133
135
  ? `${label(basename(workerDir))} Data sources from src/data: ${dataSources
134
136
  .map(source => source.name)
@@ -178,10 +180,19 @@ async function main() {
178
180
  throw new Error(`No prebuilt UI found at ${distDir}. This package was not assembled ` +
179
181
  `correctly; reinstall it.`);
180
182
  }
183
+ const prebuiltDir = resolve(__dirname, "..", "data");
181
184
  try {
182
185
  await serveUi(distDir, cliArgs.shellPort, {
183
186
  blocks: registry,
184
187
  dataSources,
188
+ prebuiltFilenames: readDataSources(prebuiltDir).map(source => source.filename),
189
+ }, () => {
190
+ const written = copyPrebuiltDataSources(prebuiltDir, dataDir);
191
+ if (written.length > 0) {
192
+ console.log(`${label(basename(workerDir))} Added pre-built data sources: ` +
193
+ written.join(", "));
194
+ }
195
+ return readDataSources(dataDir);
185
196
  });
186
197
  }
187
198
  catch (error) {
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Copy the shell's pre-built sources (`data/*.json`, shipped in the
3
+ * package) into a worker's data directory. Like materialization, existing
4
+ * worker data always wins: a bundled source is skipped when its filename is
5
+ * already taken, and also when its `key` is already claimed by any existing
6
+ * source — `key` is a source's binding/lookup identity, so a duplicate would
7
+ * make one of the two ambiguous.
8
+ */
9
+ import { copyFileSync, existsSync, mkdirSync } from "node:fs";
10
+ import { resolve } from "node:path";
11
+ import { readDataSources } from "./data-sources.js";
12
+ export function copyPrebuiltDataSources(prebuiltDir, dataDir) {
13
+ mkdirSync(dataDir, { recursive: true });
14
+ const existingKeys = new Set(readDataSources(dataDir).map(source => source.key));
15
+ const written = [];
16
+ for (const source of readDataSources(prebuiltDir)) {
17
+ const filename = `${source.filename}.json`;
18
+ const target = resolve(dataDir, filename);
19
+ if (existsSync(target) || existingKeys.has(source.key)) {
20
+ continue;
21
+ }
22
+ copyFileSync(resolve(prebuiltDir, filename), target);
23
+ written.push(filename);
24
+ }
25
+ return written.sort();
26
+ }
@@ -34,20 +34,53 @@ function injectConfig(html, config) {
34
34
  /**
35
35
  * Serve `distDir` on `port`. Unknown extensionless paths fall back to
36
36
  * `index.html`. Rejects on listen errors (e.g. the port is taken).
37
+ *
38
+ * `addPrebuiltData`, when given, backs `POST /api/prebuilt-data`: it writes
39
+ * the pre-built sources into the worker's data directory and returns
40
+ * the directory's updated contents.
37
41
  */
38
- export function serveUi(distDir, port, config) {
42
+ export function serveUi(distDir, port, config, addPrebuiltData) {
39
43
  const dist = resolve(distDir);
40
- const indexHtml = injectConfig(readFileSync(join(dist, "index.html"), "utf-8"), config);
44
+ const rawIndexHtml = readFileSync(join(dist, "index.html"), "utf-8");
45
+ // Server-owned: updated by the add endpoint, while the caller's `config`
46
+ // stays an untouched input.
47
+ let dataSources = config.dataSources;
41
48
  const server = createServer((req, res) => {
42
- let path;
49
+ let urlPath;
43
50
  try {
44
- path = normalize(decodeURIComponent(req.url?.split("?", 1)[0] ?? "/"));
51
+ urlPath = decodeURIComponent(req.url?.split("?", 1)[0] ?? "/");
45
52
  }
46
53
  catch {
47
54
  res.writeHead(400);
48
55
  res.end();
49
56
  return;
50
57
  }
58
+ // Routed on the raw URL path: normalize() is platform-specific, so it
59
+ // would rewrite "/api/..." to "\api\..." on Windows and never match.
60
+ if (urlPath === "/api/prebuilt-data") {
61
+ if (req.method !== "POST") {
62
+ res.writeHead(405, { Allow: "POST" });
63
+ res.end();
64
+ return;
65
+ }
66
+ if (addPrebuiltData === undefined) {
67
+ res.writeHead(404);
68
+ res.end();
69
+ return;
70
+ }
71
+ try {
72
+ dataSources = addPrebuiltData();
73
+ }
74
+ catch (error) {
75
+ res.writeHead(500, { "Content-Type": CONTENT_TYPES[".json"] });
76
+ res.end(JSON.stringify({ error: error.message }));
77
+ return;
78
+ }
79
+ res.writeHead(200, { "Content-Type": CONTENT_TYPES[".json"] });
80
+ res.end(JSON.stringify({ dataSources }));
81
+ return;
82
+ }
83
+ const path = normalize(urlPath);
51
84
  const filePath = join(dist, path);
52
85
  if (!filePath.startsWith(dist + sep) && filePath !== dist) {
53
86
  res.writeHead(403);
@@ -57,7 +90,9 @@ export function serveUi(distDir, port, config) {
57
90
  const ext = extname(filePath);
58
91
  if (path === "/" || path === `${sep}index.html` || ext === "") {
59
92
  res.writeHead(200, { "Content-Type": CONTENT_TYPES[".html"] });
60
- res.end(indexHtml);
93
+ // Injected per request: `dataSources` changes when pre-built data is
94
+ // added, and a reload must see the updated collection.
95
+ res.end(injectConfig(rawIndexHtml, { ...config, dataSources }));
61
96
  return;
62
97
  }
63
98
  try {
package/docs/bindings.md CHANGED
@@ -21,13 +21,12 @@ ambiguous or absent stays unmapped. Re-picking a source resets the slot's
21
21
  mappings and re-runs auto-map. Manual mapping offers only source properties
22
22
  of exactly the required type — no coercion.
23
23
 
24
- ## Initialization & live edits
24
+ ## Initialization & binding edits
25
25
 
26
26
  Once every slot is bound and every property mapped, the block initializes and
27
- renders. From then on, binding edits reach the running block through
28
- `dataSourcesChanged` without reloading it. Crossing between incomplete and
29
- complete bindings restarts the block insteadinitialization is terminal, so
30
- a block that failed to initialize can only recover through a reload.
27
+ renders. Any binding edit restarts the block: the shell recreates the block's
28
+ iframe, and the fresh initialization carries the new bindings. A block that
29
+ failed to initialize recovers the same wayfix its bindings and save.
31
30
 
32
31
  Bindings last for the page load, per block: refresh the shell and every block
33
32
  returns to unbound.
@@ -35,8 +35,8 @@ supports the following types today:
35
35
  }
36
36
  ```
37
37
 
38
- - `type` — the source's kind; `"worker"`, the only kind these files can
39
- declare today, is the default.
38
+ - `type` — the source's kind. Hand-authored files declare `"worker"` (the
39
+ default); the pre-built sources the shell adds carry `"built-in"`.
40
40
  - `key` — what blocks bind against; make it match a `dataSources` key from
41
41
  `worker.customBlock(...)` so properties auto-match. Defaults to the
42
42
  filename.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@notionhq/custom-blocks-dev-shell",
3
- "version": "0.1.11",
3
+ "version": "0.1.13",
4
4
  "description": "Local preview shell for Notion custom block workers.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -17,6 +17,7 @@
17
17
  },
18
18
  "files": [
19
19
  "bin",
20
+ "data",
20
21
  "dist",
21
22
  "dist-cli",
22
23
  "docs",