Skip to content

Latest commit

 

History

History
132 lines (97 loc) · 5.54 KB

File metadata and controls

132 lines (97 loc) · 5.54 KB

glendix

Gleam FFI 라이브러리 — Mendix Pluggable Widget API 바인딩. React는 redraw/redraw_dom, TEA 패턴은 lustre에 위임한다. Mendix API·위젯·마켓플레이스는 mendraw에 위임한다.

  • 언어: Gleam (target: JavaScript)
  • 의존성: gleam_stdlib, redraw, redraw_dom, lustre, mendraw
  • Peer deps (위젯 프로젝트): react ^19, react-dom ^19, big.js ^6 (decimal 속성 사용 시)

Gleam 문법은 docs/gleam_language_tour.md 를 참조한다.

빌드 & 검증

gleam build                          # 컴파일
gleam check                          # 타입 체크만
gleam run -m glendix/install         # 의존성 설치 + 바인딩 생성
gleam run -m glendix/dev             # 개발 서버 (HMR)
gleam run -m glendix/build           # 프로덕션 빌드 (.mpk)
gleam run -m glendix/start           # Mendix 테스트 프로젝트 연동
gleam run -m glendix/release         # 릴리즈 빌드
gleam run -m glendix/lint            # ESLint
gleam run -m glendix/lint_fix        # ESLint 자동 수정
gleam run -m mendraw/marketplace     # 마켓플레이스 위젯 다운로드

변경 후 반드시 gleam build로 빌드 확인한다.

FFI 경계 원칙 (절대 준수)

  1. 비즈니스 로직은 .gleam에 작성. .mjs는 JS 런타임 접근 담당. 외부 JS 라이브러리 연동 등 필요한 경우 FFI 어댑터가 두꺼워질 수 있다.
  2. Opaque type으로 JS 값을 감싼다. 내부 구조 직접 접근 금지.
  3. undefined/nullOption. FFI 경계에서 to_option()/from_option() 변환. Gleam에서 undefined 직접 사용 금지.
  4. Gleam 튜플 = JS 배열. #(a, b)[a, b] (useState 반환값 등).
  5. Gleam List ↔ JS Array. FFI 경계에서 toList()/.toArray() 변환.

코드 스타일

  • 주석과 doc comment는 한국어로 작성
  • 모듈별 단일 책임: 각 .gleam 파일은 하나의 타입/도메인 담당
  • @external 어노테이션: 상대 경로로 .mjs 파일 참조

핵심 API 패턴

// React (redraw) 사용
import redraw
import redraw/dom/html
import redraw/dom/attribute
import redraw/dom/events

// 위젯 진입점
import mendraw/mendix.{type JsProps}
import redraw.{type Element}

pub fn widget(props: JsProps) -> Element { ... }

// 조건부 CSS 클래스
mendix.cx([#("active", is_active), #("disabled", is_disabled)])

// 외부 JS 컴포넌트 (widget/binding)
import mendraw/interop
interop.component_el(comp, attrs, children)

// Lustre TEA 패턴
import glendix/lustre as gl
gl.use_tea(#(init_model, effect.none()), update, view)
gl.use_simple(init_model, update, view)
gl.embed(redraw_element)  // lustre view 안에 redraw 삽입

절대 하지 말 것

  • FFI .mjs에 비즈니스 로직 넣기
  • Gleam에서 JS undefined 직접 사용 (Option 변환 필수)

바인딩 & 위젯

  • 외부 React 컴포넌트: gleam.toml [tools.glendix.bindings]glendix/installglendix/binding 사용
  • Pluggable .mpk 위젯: gleam.toml [tools.mendraw.widgets.*] (자동 다운로드 → build/widgets/ 캐시) → mendraw/widget.component("Name")
  • 위젯 prop 헬퍼: mendraw/widget.prop(k, v) / widget.editable_prop(k, v, d, set) / widget.action_prop(k, fn)
  • Classic Dojo .mpk 위젯: gleam.toml [tools.mendraw.widgets.*]mendraw/classic.render(widget_id, props)
  • install 시 TOML 위젯 다운로드/캐시(mendraw) → binding_ffi.mjs(glendix), widget_ffi.mjs, classic_ffi.mjs, src/widgets/*.gleam 자동 생성(mendraw)

Editor Configuration (Jint 호환)

editor_config.gleam은 Studio Pro의 Jint(.NET JS 엔진)에서 실행된다. Gleam List 사용 금지 — WeakMap, Symbol.iterator 미지원. 복수 키는 콤마 구분 String.

PM 감지

gleam.toml[tools.glendix] pm = "pnpm" 오버라이드 우선. 없으면 lock 파일 기반: pnpm-lock.yaml → pnpm / bun.lockb·bun.lock → bun / 기본값 → npm

gleam.toml 설정 ([tools.glendix])

[tools.glendix]
pm = "pnpm"                    # PM 오버라이드 (pnpm/bun/npm)

[tools.glendix.bindings]       # 외부 React 컴포넌트 바인딩
recharts = ["PieChart", "Cell", "Tooltip", "Pie"]
"@mui/material" = ["Button", "TextField"]

[tools.mendraw.widgets.Charts] # 위젯 자동 다운로드
version = "3.0.0"
# id = 106517                  ← Content API 검색 후 자동 기록
# s3_id = "com/..."            ← 다운로드 URL (있으면 인증 없이 직접 다운로드)
  • install[tools.mendraw.widgets.*]의 위젯을 build/widgets/{name}/에 다운로드/캐시
  • meta.toml의 version과 TOML version 불일치 시 재다운로드
  • gleam cleanbuild/ 삭제 → 다음 install에서 재다운로드
  • marketplace TUI(mendraw/marketplace) 다운로드 시 자동으로 gleam.toml에 위젯 항목 추가

Mendix API 레퍼런스

Mendix 공식 문서(docs.mendix.com) 접근 불가. GitHub 소스 참조:

  • API 문서: github.com/mendix/docsapidocs-mxsdk/apidocs/pluggable-widgets/
  • 위젯 예제: github.com/mendix/web-widgetspackages/pluggableWidgets/
  • 빌드 도구: github.com/mendix/widgets-tools

핵심 개념:

  • 위젯 진입점: fn(JsProps) -> Element
  • ValueStatus: Available | Loading | Unavailable — 값 읽기 전 확인 필수
  • EditableValue.setValue() 값 변경 / ActionValue.execute() 액션 실행
  • ListValue: 페이징/정렬/필터 지원
  • mendix/filters/builders → Rollup external 처리 필요

상세 가이드

  • glendix_guide.md — 종합 사용 가이드
  • README.md — 설치 및 빠른 시작