@blocofy/cli 0.1.4 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/blocofy.mjs CHANGED
@@ -14,11 +14,12 @@ import { createInterface } from "node:readline/promises";
14
14
 
15
15
  import { credentialsPath, loadCredentials, saveCredentials } from "../lib/credentials.mjs";
16
16
  import { startDevServer } from "../lib/dev-server.mjs";
17
+ import { readLocalTemplates } from "../lib/local-theme.mjs";
17
18
  import { fetchDevSession, pullTheme, pushTheme } from "../lib/theme-sync.mjs";
18
19
  import { hyperlink, openUrl } from "../lib/term.mjs";
19
20
  import { isValidToken, isValidUrl, normalizeUrl } from "../lib/validate.mjs";
20
21
 
21
- const VERSION = "0.1.4";
22
+ const VERSION = "0.1.5";
22
23
  const args = process.argv.slice(2);
23
24
 
24
25
  /** Parse `--key value` and `--flag` (boolean) arguments. */
@@ -216,6 +217,20 @@ async function themeDev(rest) {
216
217
  console.log(`\n Press: ${keys}`);
217
218
  console.log(` Edit a theme file and save — every open view reloads automatically.\n`);
218
219
 
220
+ // Tanılama: kaç tema dosyası izleniyor? Boşsa hot-reload mümkün değil — yanlış
221
+ // dizinde ya da `theme pull` yapılmamış demektir; sebebini açıkça söyle.
222
+ const localFiles = readLocalTemplates(themeDir);
223
+ const fileCount = Object.keys(localFiles).length;
224
+ if (fileCount === 0) {
225
+ console.warn(
226
+ ` ⚠ No theme files found under ${themeDir}\n` +
227
+ ` Expected top-level folders: layout/ section/ partial/ asset/ block/ template/\n` +
228
+ ` Run this from your theme root, or fetch it first: blocofy theme pull\n`,
229
+ );
230
+ } else {
231
+ console.log(` Watching ${themeDir} — ${fileCount} theme files\n`);
232
+ }
233
+
219
234
  if (flags.dry) {
220
235
  console.log("(--dry: server not started)");
221
236
  return;
@@ -227,6 +242,18 @@ async function themeDev(rest) {
227
242
  token: creds.token,
228
243
  port,
229
244
  syncDraft: Boolean(session),
245
+ // Her kaydetmede ne olduğunu bas — "reloaded" = watch tetiklendi; "0 views"
246
+ // = hiçbir tarayıcı sekmesi bağlı değil (yanlış görünüme bakıyorsun); sync
247
+ // hatası = draft güncellenemedi (preview/editör eski kalır, local yine yenilenir).
248
+ onReload: ({ file, synced, clients, error }) => {
249
+ const what = file || "change";
250
+ if (error) {
251
+ console.error(` ↻ ${what} — draft sync failed: ${error} (local view still reloaded)`);
252
+ return;
253
+ }
254
+ const views = clients ? `${clients} view${clients === 1 ? "" : "s"}` : "no views connected";
255
+ console.log(` ↻ ${what} → ${synced ? "synced + " : ""}reloaded (${views})`);
256
+ },
230
257
  onError: (err) => {
231
258
  if (err && err.code === "EADDRINUSE") {
232
259
  console.error(`Port ${port} is in use. Try a different port: blocofy theme dev --port <n>`);
@@ -19,7 +19,7 @@ import { pushTheme } from "./theme-sync.mjs";
19
19
  * separate request); direct `/asset/*` references are served from disk. Images/JS
20
20
  * are remote (Directus/CDN), so no local serving is needed for them.
21
21
  */
22
- export function startDevServer({ dir, url, token, port, syncDraft = false, onError }) {
22
+ export function startDevServer({ dir, url, token, port, syncDraft = false, onError, onReload }) {
23
23
  const base = url.replace(/\/+$/, "");
24
24
  const clients = new Set();
25
25
 
@@ -90,16 +90,19 @@ export function startDevServer({ dir, url, token, port, syncDraft = false, onErr
90
90
  for (const client of clients) client.write("data: reload\n\n");
91
91
  };
92
92
  // Değişimde: önce taslağa senkronla (canlı-domain önizleme + editör güncel olsun),
93
- // SONRA reload yayınla → tüm görünümler en güncel taslağı çeker.
94
- const watcher = startWatch(dir, async () => {
93
+ // SONRA reload yayınla → tüm görünümler en güncel taslağı çeker. `onReload` log için:
94
+ // hangi dosya, senkron oldu mu, kaç görünüm bağlı (clients.size = açık EventSource'lar).
95
+ const watcher = startWatch(dir, async (file) => {
96
+ let error = null;
95
97
  if (syncDraft) {
96
98
  try {
97
99
  await pushTheme({ dir, url, token, draft: true });
98
- } catch {
99
- /* senkron hatası reload'u engellemesin */
100
+ } catch (err) {
101
+ error = err?.message ?? String(err); // senkron hatası reload'u engellemesin
100
102
  }
101
103
  }
102
104
  broadcast();
105
+ onReload?.({ file, synced: syncDraft && !error, clients: clients.size, error });
103
106
  });
104
107
 
105
108
  // Açılışta taslağı bir kez doldur → uzak görünümler hemen güncel local'i gösterir.
@@ -130,9 +133,11 @@ export function startDevServer({ dir, url, token, port, syncDraft = false, onErr
130
133
  */
131
134
  function startWatch(dir, onChange) {
132
135
  let timer = null;
133
- const fire = () => {
136
+ let lastFile = null;
137
+ const fire = (_event, filename) => {
138
+ if (filename) lastFile = String(filename).split(sep).join("/");
134
139
  if (timer) clearTimeout(timer);
135
- timer = setTimeout(onChange, 120);
140
+ timer = setTimeout(() => onChange(lastFile), 120);
136
141
  };
137
142
  try {
138
143
  return watch(dir, { recursive: true }, fire);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blocofy/cli",
3
- "version": "0.1.4",
3
+ "version": "0.1.5",
4
4
  "description": "Develop your Blocofy theme locally against live data with instant preview — login, theme dev, pull, push.",
5
5
  "type": "module",
6
6
  "license": "MIT",