@silentsheet/core
Version:
a quiet space to write.
176 lines (173 loc) • 4.86 kB
JavaScript
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var index_exports = {};
__export(index_exports, {
SilentSheet: () => SilentSheet
});
module.exports = __toCommonJS(index_exports);
// src/core.ts
var STORAGE_KEY = "silentsheet";
var INITIAL_TIMER_SECONDS = 15 * 60;
var DEFAULT_OPTIONS = {
content: "",
font: "sans-serif",
fontSize: 24,
theme: "sepia",
size: "medium",
timerRunning: false,
timerSeconds: INITIAL_TIMER_SECONDS,
hemingwayMode: false
};
var SilentSheet = class {
constructor(initialState) {
this.timerInterval = null;
this.subscribers = /* @__PURE__ */ new Set();
const savedState = this.loadState();
this.state = {
...DEFAULT_OPTIONS,
...savedState,
...initialState,
timerRunning: false,
timerSeconds: INITIAL_TIMER_SECONDS
};
}
loadState() {
try {
const saved = localStorage.getItem(STORAGE_KEY);
return saved ? JSON.parse(saved) : null;
} catch {
return null;
}
}
saveState() {
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify(this.state));
} catch {
}
}
startTimer() {
if (this.timerInterval) return;
this.timerInterval = setInterval(() => {
if (this.state.timerSeconds <= 0) {
this.stopTimer();
alert("Time is up! Take a moment to review what you've written.");
return;
}
this.state.timerSeconds--;
this.notifySubscribers();
}, 1e3);
}
stopTimer() {
if (this.timerInterval) {
clearInterval(this.timerInterval);
this.timerInterval = null;
}
}
getState() {
return { ...this.state };
}
getActions() {
return {
setContent: (content) => {
if (this.state.hemingwayMode) {
const lines = this.state.content.split("\n");
const newLines = content.split("\n");
if (newLines.length >= lines.length) {
const isValid = lines.every((line, index) => {
if (index === lines.length - 1) return true;
return newLines[index] === line;
});
if (isValid) {
this.state.content = content;
this.saveState();
}
}
} else {
this.state.content = content;
this.saveState();
}
this.notifySubscribers();
},
setFont: (font) => {
this.state.font = font;
this.saveState();
this.notifySubscribers();
},
setFontSize: (size) => {
this.state.fontSize = size;
this.saveState();
this.notifySubscribers();
},
setTheme: (theme) => {
this.state.theme = theme;
this.saveState();
this.notifySubscribers();
},
setSize: (size) => {
this.state.size = size;
this.saveState();
this.notifySubscribers();
},
saveContent: () => {
this.saveState();
},
clearContent: () => {
this.state.content = "";
this.saveState();
this.notifySubscribers();
},
toggleTimer: () => {
if (this.state.timerRunning) {
this.stopTimer();
this.state.timerRunning = false;
this.state.timerSeconds = INITIAL_TIMER_SECONDS;
} else {
this.state.timerRunning = true;
this.startTimer();
}
this.notifySubscribers();
},
resetTimer: () => {
this.stopTimer();
this.state.timerRunning = false;
this.state.timerSeconds = INITIAL_TIMER_SECONDS;
this.notifySubscribers();
},
toggleHemingwayMode: () => {
this.state.hemingwayMode = !this.state.hemingwayMode;
this.saveState();
this.notifySubscribers();
}
};
}
subscribeToUI(callback) {
this.subscribers.add(callback);
return () => {
this.subscribers.delete(callback);
};
}
notifySubscribers() {
this.subscribers.forEach((subscriber) => subscriber());
}
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
SilentSheet
});