Skip to main content

rynl10n 0.2.2 copy "rynl10n: ^0.2.2" to clipboard
rynl10n: ^0.2.2 copied to clipboard

앱 업데이트·심사 없이 번역을 배포하는 오픈소스 원격 로컬라이제이션 SDK. 빌드타임에 구운 번들(fallback)과 런타임 원격 오버레이의 2계층으로 항상 완전한 번역을 보장한다.

Changelog #

버전은 4개 SDK(iOS·Android·Web·Flutter) lockstep이다 — 자기 플랫폼에 변경이 없어도 같은 번호로 동시 릴리스한다(기획서 6.5). 골든 벡터가 언어 무관 계약이므로 버전 번호가 곧 "어느 조합이 정합인가"의 답이다. 0.x 구간에서는 마이너 올림이 breaking change 신호이며, 트리거는 직렬화(11.1)·매칭(11.3)· 골든 벡터 스키마 변경이다.

0.2.2 #

Android 빌드 도구와 테스트의 경고를 정리한 유지보수 릴리스다. 네 SDK를 함께 올리며, 런타임 동작·공개 API·골든 벡터 계약은 0.2.1과 같다.

  • Android bake CLI·테스트: 설정한 Json 객체를 재사용해 반복 생성 경고 4건을 제거했다.
  • Android JDK 조달: Foojay 툴체인 저장소를 명시해 JDK 다운로드 저장소 미설정 경고를 제거했다.
  • Android 문서: 최신 Android Studio SDK의 XML 메타데이터와 AGP 8의 버전 충돌을 피하는 프로젝트 전용 SDK 구성 방법을 추가했다. SDK XML 경고 해결은 개발 환경 설정이며 AAR 런타임 변경은 아니다.

0.2.1 #

SDK 런타임 동작과 골든 벡터 계약은 0.2.0과 같다. 네 SDK의 버전을 함께 올린 유지보수 릴리스다.

  • iOS: 테스트 빌드의 미사용 변수·반환값과 불필요한 동시성 선언 경고를 제거했다.
  • SwiftPM 소비 예제: 경로 의존의 패키지 이름을 명시해 저장소 디렉터리 이름이 달라도 빌드된다.
  • SDK 문서: bake 실행 위치·산출물 경로, 카나리 참여 조건, Web 푸시 연결과 폴링 구성을 실제 코드에 맞췄다.
  • Android 개발 도구: Gradle 데몬을 JDK 21로 고정하고 로컬 검증에서 컴파일과 테스트 실행을 확인한다.

0.2.0 #

마이너를 올리는 이유는 ICU 인자 이름 경계다 — 같은 카탈로그라도 비ASCII 플레이스홀더가 있는 키는 화면에 보이는 값과 bake 산출물이 전과 달라진다(아래 첫 항목). 4개 SDK lockstep이라 자기 플랫폼에 변경이 없어도 같은 번호로 함께 오른다.

  • ICU 인자 이름 경계를 스펙대로 넓혔다 — 인자 이름 스캔이 [A-Za-z0-9_]+라 {이름}·{имя} 같은 비ASCII 플레이스홀더가 리터럴로 취급됐다. argName은 Pattern_Syntax도 Pattern_White_Space도 아닌 문자 1개 이상이다. 같은 가정이 서명·런타임 치환·bake 변환 셋에 흩어져 있어 정의를 언어당 한 파일로 모았고, 골든 벡터 signature.json이 그 경계를 4개 언어의 계약으로 잡는다. 올리면 달라지는 것:
    • 런타임 치환 — {이름}이 인자로 치환된다. 전에는 중괄호째 화면에 보였다.
    • 포맷 가드 — 원래 플레이스홀더가 없던 키에 오버레이가 {이름}을 새로 넣으면 이제 가드가 막고 그 키만 번들 값으로 물러난다. 전에는 서명이 둘 다 비어 있어 가드를 그냥 통과했다 (이것이 고친 결함이다). 가드는 기기에서 오버레이·번들 값의 서명을 같은 SDK 코드로 각각 계산하므로, 서버에 저장된 서명과는 무관하고 다시 저장할 것은 없다.
    • bake 산출물 — 네이티브 변환이 비ASCII 인자를 위치 인자(.xcstrings·strings.xml)와 .arb placeholders 키로 옮긴다. 해당 키가 있으면 다시 빌드한 산출물이 전과 달라진다.
    • {★}·{→} 같은 Pattern_Syntax 기호는 전과 같이 플레이스홀더가 아니다.
  • release_applied 텔레메트리 이벤트 추가 — 델타가 없는 릴리스(첫 게시·base 롤백)와 카나리 rollout 밖 기기는 overlay_applied가 영영 0이라, 서버에서 "아무도 안 쓴다"와 "쓴다고 말할 방법이 없다"가 똑같이 보였다. 네 SDK가 swap 한 자리에서 같은 판정을 한다. overlay_applied의 뜻은 그대로다 — 건전성 비율의 분모라 오버레이를 받은 적 없는 기기를 섞으면 거부율이 실제보다 건강해 보인다. 텔레메트리는 여전히 옵트인 2겹이고 올라가는 필드도 그대로다.
  • Android: bake CLI가 --descriptions를 실제로 넘긴다 — 약속한 strings.xml XML 주석이 그동안 구워지지 않았다(변환기·골든은 이미 맞았고 CLI 배선만 빠져 있었다). 빌드 툴체인은 Kotlin 2.1.20이 하한이다.
  • iOS: 빌드 플러그인이 폐기된 PackagePlugin.Path 대신 URL API를 쓴다 — 소비 앱 빌드 로그에 찍히던 경고 17건이 사라진다. 동작 변화는 없다. Xcode 앱 타깃의 플러그인 경로를 실제 앱으로 확인했다.

0.1.0 #

첫 공개 릴리스.

  • 2계층 resolve — 빌드타임에 구운 번들(fallback) 위에 런타임 원격 오버레이를 키 단위로 덮는다. 오버레이는 sparse, 적용은 원자적(체크섬 후 스왑), tombstone(삭제 마커) 지원.
  • 로케일 fallback 체인 — BCP 47 태그를 구체→일반으로 절단(ko-KR → ko → 기본 로케일)하되 각 로케일 단계 안에서 오버레이·번들을 모두 확인한 뒤 다음 로케일로 넘어간다(로케일 우선 원칙). 조회 로케일은 RynL10nClient(locale: ...)로 정하며 릴리스 매칭 축과 별개다.
  • 포맷 안전 가드 — 오버레이 값의 플레이스홀더 서명이 번들과 다르면 그 키만 번들로 물러난다. 잘못된 원격 문자열로 인한 런타임 크래시를 차단한다.
  • 버전 격리 — 정적 manifest를 클라이언트가 읽어 자기 앱 버전에 맞는 릴리스를 스스로 고른다 (서버 라우팅 없음). 매칭 전략 3종: semver-range · exact-label · integer-range.
  • 갱신 3종 — 수동 update() · 주기 폴링(보장선) · SSE 푸시(지연 단축, 옵트인).
  • 익명 집계 텔레메트리(옵트인 2겹) — 수집·전송 각각 켜야 하며 서버 스키마 5개 필드만 올라간다. 키 이름·번역 값·기기 식별자는 구조적으로 나가지 않는다.
  • 어댑터 분리 — 코어(rynl10n.dart)는 HTTP·저장소를 주입받는 순수 Dart다. 진입점은 둘 중 택일: rynl10n_io.dart(dart:io, 추가 의존성 0, 웹 컴파일 불가) · rynl10n_http.dart(package:http, Flutter Web 포함 전 플랫폼).
  • 코어 알고리즘(JCS 정규화·해시·resolve·매칭·카나리)은 TS 참조 구현과 골든 벡터로 바이트·해시·동작 정합을 기계 검증한다 — 4개 언어가 같은 벡터를 읽는다.

알려진 제약: Flutter Web에서 httpPushConnect는 SSE가 스트리밍되지 않는다(BrowserClient=XHR). 웹은 EventSource를 PushConnect로 감싸 넣으면 되고, 그대로 둬도 폴링이 보장선이라 기능은 깨지지 않고 갱신 지연만 남는다.

0
likes
130
points
310
downloads

Documentation

Documentation
API reference

Publisher

unverified uploader

Weekly Downloads

앱 업데이트·심사 없이 번역을 배포하는 오픈소스 원격 로컬라이제이션 SDK. 빌드타임에 구운 번들(fallback)과 런타임 원격 오버레이의 2계층으로 항상 완전한 번역을 보장한다.

Repository (GitHub)
View/report issues

Topics

#localization #i18n

License

Apache-2.0 (license)

Dependencies

crypto, http, unorm_dart

More

Packages that depend on rynl10n