Skip to content

actionbook-core 0.8.0

Install from the command line:
Learn more about npm packages
$ npm install @sendbird/actionbook-core@0.8.0
Install via package.json:
"@sendbird/actionbook-core": "0.8.0"

About this version

actionbook-core

Actionbook 문서의 프레임워크 독립적 코어 라이브러리.

Tiptap/ProseMirror에 종속되지 않는 자체 AST 모델, 마크다운 파서/시리얼라이저, Jinja 조건식 평가기, 그리고 구조적 편집 Operation 시스템을 제공합니다.

왜 필요한가

기존 Actionbook 에디터의 문서 모델은 ProseMirror 스키마에 강하게 결합되어 있어서:

  • 서버 사이드에서 문서를 파싱/검증할 수 없음
  • 에디터를 교체하려면 데이터 모델까지 함께 바꿔야 함
  • Jinja 프리뷰 등 부가 기능이 에디터 DOM에 의존

이 라이브러리는 순수 TypeScript로 작성되어 브라우저, Node.js, 서버리스 환경 어디서든 동작합니다.

빠른 시작

import {
  parseMarkdown,
  serializeToMarkdown,
  fromProseMirrorJSON,
  validate,
  doc, paragraph, text, bold, resourceTag, jumpPoint,
} from '@sb/actionbook-core';

// 마크다운 파싱
const ast = parseMarkdown('# Title\n\nUse {{tool:t1:My Tool}} at ^START^');

// 빌더로 직접 생성
const manual = doc(
  paragraph(text('Hello '), text('bold', [bold()]), resourceTag('tool', 't1', 'Tool')),
);

// 스키마 검증
const errors = validate(ast); // [] 이면 정상

// 마크다운 출력
const md = serializeToMarkdown(ast);

// ProseMirror JSON 변환 (기존 editor_data 호환)
const ast2 = fromProseMirrorJSON(existingEditorData);

모듈 구조

모듈 설명
ast/ 타입 정의, 빌더, 순회, 경로 주소 체계
schema/ AST 구조 검증 (URL 프로토콜 allowlist 포함)
markdown/ mdast 기반 파서/시리얼라이저 + 커스텀 구문 플러그인
json/ v3 포맷 직렬화 + 레거시 자동 감지 역직렬화
compat/ ProseMirror JSONContent → AST 변환
operations/ 구조적 편집 (Insert/Delete/Replace + undo 지원)
jinja/ 순수 텍스트 기반 Jinja 블록 파서 + 안전한 조건식 평가기
utils/ 리소스 태그 추출, 중복 Jump Point 탐지

테스트

cd libs/actionbook-core
npx vitest run

12개 파일, 206개 테스트. 커버리지: AST 빌더/순회, 마크다운 roundtrip, ProseMirror 호환, 스키마 검증, Jinja 평가기 보안 케이스, Operation 타입 안전성, 역직렬화 경계, URL 새니타이제이션.

보안 설계

이 라이브러리는 신뢰되지 않는 입력(사용자가 편집한 마크다운, 외부에서 전달된 editor_data)을 처리하도록 설계되었습니다.

위협 대응
Jinja 조건식을 통한 임의 코드 실행 new Function / eval 제거. 재귀 하강 파서로 화이트리스트 연산자만 평가
악의적 AST 주입 (malformed editor_data) 모든 역직렬화 경계에서 validate() 강제 적용
javascript: URL을 통한 XSS 파서, PM 변환기, 스키마 검증 3중 차단 (http/https/mailto/tel 만 허용)
깊게 중첩된 입력으로 stack overflow 모든 재귀 함수에 MAX_DEPTH 가드 (128)
Operation으로 잘못된 AST 생성 부모-자식 타입 매트릭스 검증 + 경로 유효성 체크

현재 한계

기존 에디터와 아직 통합되지 않음

이 라이브러리는 독립 모듈로 동일성 테스트만 완료된 상태입니다. 기존 에디터 코드를 실제로 교체하는 작업은 아직 수행되지 않았으며, 점진적으로 진행할 계획입니다.

교체 대상:

  • converters.tsactionbookToAST()
  • processResourceTags.ts → 파서가 직접 노드 생성하므로 삭제 가능
  • editorConverter.tsparseMarkdown() + serializeToMarkdown()
  • JinjaPreview/jinja/ 모듈

마크다운 파서 간 미세한 차이

기존: tiptap-markdown (markdown-it 기반) → 이 라이브러리: mdast (micromark 기반)

대부분의 마크다운에서 동일한 결과를 내지만, edge case에서 차이가 발생할 수 있습니다:

  • Loose/tight list 판단: 빈 줄이 포함된 리스트의 처리 방식이 다를 수 있음
  • 리스트 들여쓰기: 2칸 vs 4칸 인식 차이
  • HTML 인라인: 이 라이브러리는 HTML을 지원하지 않음 (설계 의도)

완화 방안: 실제 프로덕션 데이터에서 추출한 마크다운 fixture를 추가하여 차이를 조기에 발견해야 합니다.

Jinja evaluator 제약

안전성을 위해 재귀 하강 파서를 사용하므로, Jinja2의 전체 표현식 문법을 지원하지 않습니다.

지원됨: ==, !=, <, >, <=, >=, and, or, not, in, is, is not, 괄호, 문자열/숫자/불리언/None 리터럴, 점 표기법 변수

미지원:

  • 필터 (value | upper, items | length)
  • 함수 호출 (len(items), range(10))
  • 리스트/딕셔너리 리터럴 ([1, 2], {"k": "v"})
  • 삼항 ("a" if cond else "b")
  • not in 연산자
  • 슬라이싱 (items[0])

실제 Actionbook에서 사용 중인 조건식이 이 범위를 넘는다면 evaluator 확장이 필요합니다.

Operations 모듈은 기반만 구현

  • 노드 단위 편집만 가능: 텍스트 노드 내부의 문자 레벨 편집(split/merge)은 미지원
  • 동시성 미지원: CRDT/OT 변환 로직 없음. NodePath + Transaction 구조가 확장 포인트로 설계되어 있지만 실제 conflict resolution은 없음
  • 빈 컨테이너 허용: 모든 listItem을 삭제한 후 빈 bulletList가 남는 등의 의미적 무결성은 검증하지 않음 (schema validation에서는 잡힘)

번들 크기 미검증

micromark + mdast-util 생태계 의존성이 추가됨. 루트 프로젝트가 이미 remark-gfm을 쓰고 있어 중복은 적을 것으로 예상하지만, 실제 tree-shaking 후 번들 크기 측정은 아직 하지 않았습니다.

향후 계획

단기 (통합 단계)

  1. 프로덕션 fixture 확보: 실제 고객 Actionbook 데이터에서 마크다운 + PM JSON 쌍을 추출하여 동일성 테스트 보강
  2. 기존 코드 점진적 교체: 가장 리스크가 낮은 읽기 전용 경로(프리뷰, 내보내기)부터 이 라이브러리로 전환
  3. 번들 크기 측정: Vite 빌드에서의 실제 기여도 확인

중기 (에디터 독립화)

  1. actionbook-renderer: 자체 AST를 입력으로 받는 React 읽기 전용 렌더러. 프리뷰에 먼저 적용
  2. Jinja evaluator 확장: 필터, not in, 리스트 리터럴 등 실제 사용되는 패턴 추가
  3. 서버 사이드 검증: Node.js 서버에서 마크다운 파싱/Jinja 변수 추출 수행

장기 (에디터 교체)

  1. actionbook-editor: 자체 AST + Operation 기반의 편집 가능한 에디터
  2. CRDT 협업 편집: Operation 모델 위에 Yjs/Automerge 어댑터
  3. History 시스템: Transaction + invertOperation() 기반 undo/redo 스택

리스크

리스크 가능성 영향 완화
remark↔markdown-it 파싱 차이로 데이터 깨짐 중간 높음 프로덕션 fixture 테스트, normalize 함수, 이중 실행 비교
Jinja evaluator가 실제 사용 패턴을 커버 못함 낮음 중간 실사용 조건식 수집 → tokenizer/parser 확장
번들 크기 증가 낮음 낮음 tree-shaking 확인, lazy import 검토
^id^ 와 기존 에디터의 caret 충돌 낮음 낮음 알파벳+언더스코어 제한으로 범위 축소

Details


Assets

  • actionbook-core-0.8.0.tgz

Download activity

  • Total downloads 2
  • Last 30 days 0
  • Last week 0
  • Today 0

Recent versions

View all