@jbpark/live-editor 1.5.0 → 1.7.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.
@@ -30,7 +30,10 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
30
30
 
31
31
  //#endregion
32
32
  //#region src/constants/index.ts
33
- const CONFIG = { CACHE_LIMIT: 50 };
33
+ const CONFIG = {
34
+ CACHE_LIMIT: 50,
35
+ DOCUMENT_CACHE_LIMIT: 4
36
+ };
34
37
  const DATA_ATTR = {
35
38
  ID: "data-id",
36
39
  BINDING: "data-binding",
@@ -40183,8 +40186,16 @@ var require_lib = /* @__PURE__ */ __commonJSMin(((exports) => {
40183
40186
  //#region src/utils/cache.ts
40184
40187
  const createBoundedCache = (limit, onEvict) => {
40185
40188
  const store = /* @__PURE__ */ new Map();
40189
+ const get = (key) => {
40190
+ if (!store.has(key)) return;
40191
+ const value = store.get(key);
40192
+ store.delete(key);
40193
+ store.set(key, value);
40194
+ return value;
40195
+ };
40186
40196
  const set = (key, value) => {
40187
- if (store.size >= limit) {
40197
+ if (store.has(key)) store.delete(key);
40198
+ else if (store.size >= limit) {
40188
40199
  const oldestKey = store.keys().next().value;
40189
40200
  if (oldestKey !== void 0) {
40190
40201
  const oldestValue = store.get(oldestKey);
@@ -40196,7 +40207,7 @@ const createBoundedCache = (limit, onEvict) => {
40196
40207
  };
40197
40208
  return {
40198
40209
  has: (key) => store.has(key),
40199
- get: (key) => store.get(key),
40210
+ get,
40200
40211
  set,
40201
40212
  delete: (key) => store.delete(key),
40202
40213
  clear: () => store.clear(),
@@ -40206,56 +40217,26 @@ const createBoundedCache = (limit, onEvict) => {
40206
40217
  };
40207
40218
  };
40208
40219
 
40209
- //#endregion
40210
- //#region src/utils/ast/helpers.ts
40211
- var import_lib$1 = /* @__PURE__ */ __toESM(require_lib$3(), 1);
40212
- var import_lib$2 = require_lib$7();
40213
- var import_lib$3 = /* @__PURE__ */ __toESM(require_lib$4(), 1);
40214
- const wrap = (code) => {
40215
- return `<>${code}</>`;
40216
- };
40217
- const unwrap = (generated) => {
40218
- return generated.replace(/^<>\s*/g, "").replace(/\s*<\/>\s*;?\s*$/g, "").trim();
40219
- };
40220
- const attrValue = ({ value, isStringLiteral }) => {
40221
- if (value === null) return null;
40222
- if (isStringLiteral) return import_lib$3.stringLiteral(value);
40223
- const trimmed = value.trim();
40224
- if (REGEX.NUMBER.test(trimmed)) return import_lib$3.jsxExpressionContainer(import_lib$3.numericLiteral(parseFloat(trimmed)));
40225
- if (REGEX.BOOLEAN_OR_NULL.test(trimmed)) {
40226
- const expr = (0, import_lib$2.parseExpression)(trimmed, { plugins: ["jsx", "typescript"] });
40227
- return import_lib$3.jsxExpressionContainer(expr);
40228
- }
40229
- try {
40230
- const expr = (0, import_lib$2.parseExpression)(trimmed, { plugins: ["jsx", "typescript"] });
40231
- return import_lib$3.jsxExpressionContainer(expr);
40232
- } catch {
40233
- return import_lib$3.stringLiteral(trimmed);
40234
- }
40235
- };
40236
- const generateCode = (node) => {
40237
- return (0, import_lib$1.default)(node, { jsescOption: { minimal: true } }).code;
40238
- };
40239
-
40240
40220
  //#endregion
40241
40221
  //#region src/utils/ast/document.ts
40242
- var import_lib = /* @__PURE__ */ __toESM(require_lib(), 1);
40222
+ var import_lib = require_lib$7();
40223
+ var import_lib$1 = /* @__PURE__ */ __toESM(require_lib(), 1);
40224
+ var import_lib$2 = /* @__PURE__ */ __toESM(require_lib$4(), 1);
40243
40225
  const APP_CONTAINER_ID = "app-container";
40244
40226
  const SECTION_TAG = "section";
40245
40227
  const DATA_NAME_ATTR = "data-name";
40246
40228
  const getTagName = (element) => {
40247
40229
  const name = element.openingElement.name;
40248
- return import_lib$3.isJSXIdentifier(name) ? name.name : "";
40230
+ return import_lib$2.isJSXIdentifier(name) ? name.name : "";
40249
40231
  };
40250
40232
  const getAttrValue = (element, attrName) => {
40251
- const attr = element.openingElement.attributes.find((a) => import_lib$3.isJSXAttribute(a) && import_lib$3.isJSXIdentifier(a.name) && a.name.name === attrName);
40252
- return attr && import_lib$3.isStringLiteral(attr.value) ? attr.value.value : void 0;
40233
+ const attr = element.openingElement.attributes.find((a) => import_lib$2.isJSXAttribute(a) && import_lib$2.isJSXIdentifier(a.name) && a.name.name === attrName);
40234
+ return attr && import_lib$2.isStringLiteral(attr.value) ? attr.value.value : void 0;
40253
40235
  };
40254
- const isSectionElement = (node) => import_lib$3.isJSXElement(node) && getTagName(node) === SECTION_TAG;
40255
- const isBlankJSXText = (node) => import_lib$3.isJSXText(node) && !node.value.trim();
40236
+ const isSectionElement = (node) => import_lib$2.isJSXElement(node) && getTagName(node) === SECTION_TAG;
40256
40237
  const findContainer = (ast) => {
40257
40238
  let container;
40258
- (0, import_lib.default)(ast, { JSXElement(path) {
40239
+ (0, import_lib$1.default)(ast, { JSXElement(path) {
40259
40240
  if (getAttrValue(path.node, "id") === APP_CONTAINER_ID) {
40260
40241
  container = path.node;
40261
40242
  path.stop();
@@ -40263,22 +40244,27 @@ const findContainer = (ast) => {
40263
40244
  } });
40264
40245
  return container;
40265
40246
  };
40266
- const parseCache = createBoundedCache(CONFIG.CACHE_LIMIT);
40267
- const parseSource = (code) => {
40268
- const cached = parseCache.get(code);
40269
- if (cached) return import_lib$3.cloneNode(cached, true);
40270
- const ast = (0, import_lib$2.parse)(code, {
40271
- sourceType: "module",
40272
- plugins: ["jsx", "typescript"]
40273
- });
40274
- parseCache.set(code, ast);
40275
- return import_lib$3.cloneNode(ast, true);
40247
+ const findOutermostSections = (children) => {
40248
+ const sections = [];
40249
+ for (const child of children) {
40250
+ if (isSectionElement(child)) {
40251
+ sections.push(child);
40252
+ continue;
40253
+ }
40254
+ if (import_lib$2.isJSXElement(child) || import_lib$2.isJSXFragment(child)) sections.push(...findOutermostSections(child.children));
40255
+ }
40256
+ return sections;
40276
40257
  };
40277
- const parseDocument = (code) => {
40258
+ const documentCache = createBoundedCache(CONFIG.DOCUMENT_CACHE_LIMIT);
40259
+ const buildDocument = (code) => {
40278
40260
  try {
40279
- const ast = parseSource(code);
40261
+ const ast = (0, import_lib.parse)(code, {
40262
+ sourceType: "module",
40263
+ plugins: ["jsx", "typescript"]
40264
+ });
40280
40265
  const container = findContainer(ast);
40281
40266
  return container ? {
40267
+ code,
40282
40268
  ast,
40283
40269
  container
40284
40270
  } : void 0;
@@ -40287,40 +40273,51 @@ const parseDocument = (code) => {
40287
40273
  return;
40288
40274
  }
40289
40275
  };
40276
+ const parseDocument = (code) => {
40277
+ const cached = documentCache.get(code);
40278
+ if (cached !== void 0) return cached ?? void 0;
40279
+ const doc = buildDocument(code);
40280
+ documentCache.set(code, doc ?? null);
40281
+ return doc;
40282
+ };
40290
40283
  const clearDocumentParseCache = () => {
40291
- parseCache.clear();
40284
+ documentCache.clear();
40292
40285
  };
40293
- const getSections = (doc) => doc.container.children.filter(isSectionElement).map((node, index) => ({
40286
+ const getSections = (doc) => findOutermostSections(doc.container.children).map((node, index) => ({
40294
40287
  id: `${index}`,
40295
40288
  name: getAttrValue(node, DATA_NAME_ATTR) || `${index + 1}번째 컴포넌트`,
40296
- code: generateCode(node)
40289
+ code: doc.code.slice(node.start, node.end)
40297
40290
  }));
40298
- const generateDocumentCode = (doc) => generateCode(doc.ast);
40299
- const parseSectionNode = (code) => {
40300
- try {
40301
- const expr = (0, import_lib$2.parseExpression)(code, { plugins: ["jsx", "typescript"] });
40302
- return import_lib$3.isJSXElement(expr) ? expr : void 0;
40303
- } catch (e) {
40304
- console.warn("⚠️ Failed to parse section", e);
40305
- return;
40306
- }
40291
+ const generateDocumentCode = (doc) => doc.code;
40292
+ const getContainerInnerSpan = (container) => {
40293
+ if (!container.closingElement) return;
40294
+ return {
40295
+ start: container.openingElement.end,
40296
+ end: container.closingElement.start
40297
+ };
40307
40298
  };
40299
+ const spliceCode = (code, start, end, replacement) => code.slice(0, start) + replacement + code.slice(end);
40308
40300
  const replaceDocumentSections = (fullCode, sectionCodes) => {
40309
40301
  const doc = parseDocument(fullCode);
40310
40302
  if (!doc) return fullCode;
40311
- const nextSections = sectionCodes.map(parseSectionNode).filter((node) => Boolean(node));
40312
- const preserved = doc.container.children.filter((child) => !isSectionElement(child) && !isBlankJSXText(child));
40313
- doc.container.children = [...nextSections, ...preserved];
40314
- return generateDocumentCode(doc);
40303
+ const sections = findOutermostSections(doc.container.children);
40304
+ const replacement = sectionCodes.join("\n");
40305
+ if (sections.length > 0) {
40306
+ const start = sections[0].start;
40307
+ const end = sections[sections.length - 1].end;
40308
+ return spliceCode(fullCode, start, end, replacement);
40309
+ }
40310
+ const span = getContainerInnerSpan(doc.container);
40311
+ return span ? spliceCode(fullCode, span.end, span.end, replacement) : fullCode;
40315
40312
  };
40316
- const generateSectionPreview = (fullCode, sectionCode) => {
40313
+ const generateSectionPreview = (fullCode, sectionCode) => generateSectionPreviews(fullCode, [sectionCode])[0];
40314
+ const generateSectionPreviews = (fullCode, sectionCodes) => {
40317
40315
  const doc = parseDocument(fullCode);
40318
- const sectionNode = parseSectionNode(sectionCode);
40319
- if (!doc || !sectionNode) return fullCode;
40320
- doc.container.children = [sectionNode];
40321
- return generateDocumentCode(doc);
40316
+ const span = doc && getContainerInnerSpan(doc.container);
40317
+ if (!span) return sectionCodes.map(() => fullCode);
40318
+ return sectionCodes.map((sectionCode) => spliceCode(fullCode, span.start, span.end, sectionCode));
40322
40319
  };
40323
40320
 
40324
40321
  //#endregion
40325
- export { __toESM as S, DATA_ATTR as _, parseDocument as a, REGEX as b, generateCode as c, createBoundedCache as d, require_lib as f, CONFIG as g, BINDING_PROP as h, getSections as i, unwrap as l, require_lib$7 as m, generateDocumentCode as n, replaceDocumentSections as o, require_lib$4 as p, generateSectionPreview as r, attrValue as s, clearDocumentParseCache as t, wrap as u, DEFAULT_TEMPLATE as v, TS_PATTERNS as x, DRAGGABLE_ITEMS as y };
40326
- //# sourceMappingURL=document-BGG0pNR2.mjs.map
40322
+ export { DRAGGABLE_ITEMS as _, getSections as a, __toESM as b, createBoundedCache as c, require_lib$4 as d, require_lib$7 as f, DEFAULT_TEMPLATE as g, DATA_ATTR as h, generateSectionPreviews as i, require_lib as l, CONFIG as m, generateDocumentCode as n, parseDocument as o, BINDING_PROP as p, generateSectionPreview as r, replaceDocumentSections as s, clearDocumentParseCache as t, require_lib$3 as u, REGEX as v, TS_PATTERNS as y };
40323
+ //# sourceMappingURL=document-kU_tXfS_.mjs.map