| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- # FILE: app/utils/AppDB.coffee
- class AppDB
- currentLanguage: 'ru'
- currentProject: 's5l.ru'
- designDocVersion: '1.1' # управление версией дизайна
- constructor: ->
- @localDB = new PouchDB('s5l_local')
- @remoteDB = new PouchDB('https://oleg:631074@couchdb.favt.ru.net/s5lru/')
- @syncHandler = null
- init: ->
- try
- await @remoteDB.info()
- debug.log "Remote DB connected"
- await @ensureDesignDocs()
- await @ensureDefaultContent()
- @startSync()
- AppDB.currentLanguage = globalThis._?.appState?.currentLanguage or 'ru'
- catch e
- debug.log "DB init failed:", e
- startSync: ->
- @syncHandler = @localDB.sync(@remoteDB, { live: true, retry: true })
- .on 'error', (err) -> debug.log "Sync error:", err
- ensureDesignDocs: ->
- adminDoc =
- _id: '_design/admin'
- version: @designDocVersion
- views:
- byPath:
- map: (doc) ->
- if doc.type == 'page'
- emit [doc.domain, doc.path], doc
- .toString()
- byType:
- map: (doc) ->
- emit doc.type, doc
- .toString()
- try
- existing = await @remoteDB.get('_design/admin')
- if existing.version != @designDocVersion
- adminDoc._rev = existing._rev
- await @remoteDB.put(adminDoc)
- debug.log "Design doc updated to v#{@designDocVersion}"
- catch
- await @remoteDB.put(adminDoc)
- debug.log "Design doc created v#{@designDocVersion}"
- ensureDefaultContent: ->
- defaultHome =
- _id: 'page::s5l.ru::/'
- type: 'page'
- domain: 's5l.ru'
- path: '/'
- translations:
- ru:
- title: "s5l.ru — мультиязычная offline-first платформа"
- subtitle: "Разрабатывайте быстро, работайте везде"
- content: '''
- # Добро пожаловать на s5l.ru
- **s5l.ru** — это платформа для быстрого запуска веб-проектов с поддержкой:
- - offline-first через PouchDB/CouchDB
- - автоматического переключения языка
- - динамической подгрузки контента
- - полной WCAG 2.2-совместимости
- Все тексты хранятся в базе и легко редактируются через админку.
- '''
- gallery: [
- { src: "/assets/hero-s5l.svg", alt: "Hero illustration" }
- ]
- en:
- title: "s5l.ru — multilingual offline-first platform"
- subtitle: "Build fast, work anywhere"
- content: '''
- # Welcome to s5l.ru
- **s5l.ru** is a platform for rapid web project launches with:
- - offline-first via PouchDB/CouchDB
- - automatic language switching
- - dynamic content loading
- - full WCAG 2.2 compliance
- All text is stored in the database and editable via admin panel.
- '''
- gallery: [
- { src: "/assets/hero-s5l.svg", alt: "Hero illustration" }
- ]
- tj:
- title: "s5l.ru — платформаи бисёрзабон ва аввал офлайн"
- subtitle: "Бисёр тез бунёд кунед, дар ҳама ҷо кор кунед"
- content: '''
- # Ба s5l.ru хуш омадед
- **s5l.ru** — ин платформа барои оғози тези лоиҳаҳои веб аст бо:
- - офлайн-аввал аз рӯи PouchDB/CouchDB
- - ивази худкори забон
- - боркунии динамикӣ
- - мутобиқати пурраи WCAG 2.2
- Ҳамаи матнҳо дар база нигоҳ дошта мешаванд ва аз ҷониби панели маъмури озодона таҳрир карда мешаванд.
- '''
- gallery: [
- { src: "/assets/hero-s5l.svg", alt: "Hero illustration" }
- ]
- try
- await @remoteDB.get('page::s5l.ru::/')
- catch
- await @remoteDB.put(defaultHome)
- debug.log "Default home page created"
- getDocumentByPath: (path, lang = @currentLanguage) ->
- path = path or '/'
- try
- result = await @localDB.query('admin/byPath', { key: [@currentProject, path], include_docs: true })
- if result.rows.length > 0
- doc = result.rows[0].doc
- return doc
- else
- throw new Error "Document not found"
- catch e
- debug.log "Fallback for path:", path, "lang:", lang
- # fallback to English if not found
- if lang != 'en'
- return await @getDocumentByPath(path, 'en')
- else
- throw new Error "Document not available even in English"
- module.exports = AppDB
|