Skip to content

Commit

Permalink
feat: refresh vue components when bundle list changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Demivan committed Aug 29, 2019
1 parent 6f4770d commit bfc3039
Show file tree
Hide file tree
Showing 9 changed files with 101 additions and 8 deletions.
7 changes: 6 additions & 1 deletion rollup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,12 @@ export default {
// Compile TypeScript files
typescript({ useTsconfigDeclarationDir: true }),
// Allow bundling cjs modules (unlike webpack, rollup doesn't understand cjs)
commonjs(),
commonjs({
namedExports: {
'cached-iterable': ['CachedSyncIterable'],
'@fluent/sequence': ['mapBundleSync']
}
}),
// Allow node_modules resolution, so you can use 'external' to control
// which external modules to include in the bundle
// https://github.com/rollup/rollup-plugin-node-resolve#usage
Expand Down
2 changes: 1 addition & 1 deletion src/directive.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { DirectiveBinding } from 'vue/types/options'
import { VNode } from 'vue/types/vnode'
import { warn } from './util/warn'
import { FluentVueObject } from '../types'
import { FluentVueObject } from './types'

function translate(el: HTMLElement, fluent: FluentVueObject, binding: DirectiveBinding) {
const key = binding.arg
Expand Down
35 changes: 30 additions & 5 deletions src/fluent-vue.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,47 @@
import Vue from 'vue'
import { CachedSyncIterable } from 'cached-iterable'
import { mapBundleSync } from '@fluent/sequence'
import { warn } from './util/warn'

import { FluentVueObject, FluentVueOptions } from '../types'
import { Vue, VueConstructor } from 'vue/types/vue'
import { FluentVueObject, FluentVueOptions } from './types'
import { VueConstructor } from 'vue/types/vue'
import { Pattern, FluentBundle } from '@fluent/bundle'

export default class FluentVue implements FluentVueObject {
bundles: CachedSyncIterable
private subscribers: Map<Vue, boolean>
private bundlesIterable: CachedSyncIterable
private _bundles: FluentBundle[]

subscribe(vue: Vue): void {
this.subscribers.set(vue, true)
}
unsubscribe(vue: Vue): void {
this.subscribers.delete(vue)
}

get bundles(): FluentBundle[] {
return this._bundles
}

set bundles(bundles: FluentBundle[]) {
this._bundles = bundles
this.bundlesIterable = CachedSyncIterable.from(this.bundles)

for (const subscriber of this.subscribers.keys()) {
subscriber.$forceUpdate()
}
}

static install: (vue: VueConstructor<Vue>) => void

constructor(options: FluentVueOptions) {
this.bundles = CachedSyncIterable.from(options.bundles)
this.subscribers = new Map<Vue, boolean>()
this._bundles = options.bundles
this.bundlesIterable = CachedSyncIterable.from(this.bundles)
}

getBundle(key: string): FluentBundle {
return mapBundleSync(this.bundles, key)
return mapBundleSync(this.bundlesIterable, key)
}

getMessage(bundle: FluentBundle | null, key: string) {
Expand Down
8 changes: 8 additions & 0 deletions src/mixin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,21 @@ export default {
) {
this._fluent = options.parent.$fluent
}

if (!this._fluent) {
return
}

this._fluent.subscribe(this)
},

beforeDestroy(this: Vue): void {
if (!this._fluent) {
return
}

this._fluent.unsubscribe(this)

this.$nextTick(() => {
this._fluent = undefined
})
Expand Down
2 changes: 1 addition & 1 deletion src/types/globals.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Vue } from 'vue/types/vue'
import { FluentVueObject } from '../../types'
import { FluentVueObject } from '.'

declare module 'vue/types/vue' {
interface Vue {
Expand Down
3 changes: 3 additions & 0 deletions types/index.d.ts → src/types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ export interface FluentVueObject {
getMessage(bundle: FluentBundle | null, key: string): MessageInfo | null
formatPattern(bundle: FluentBundle, message: Pattern, value?: object, errors?: string[]): string
format(key: string, value?: object): string

subscribe(vue: Vue): void
unsubscribe(vue: Vue): void
}

export interface FluentVueOptions {
Expand Down
4 changes: 4 additions & 0 deletions test/__snapshots__/change-language.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,7 @@
exports[`language change can work with multiple bundles 1`] = `<a href="/foo">текст посилання</a>`;

exports[`language change falls back to previous bundle 1`] = `<a href="/foo">link text</a>`;

exports[`language change updates when updating bundles array 1`] = `<a href="/foo">текст посилання</a>`;

exports[`language change updates when updating bundles array 2`] = `<a href="/foo">link text</a>`;
47 changes: 47 additions & 0 deletions test/change-language.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,51 @@ describe('language change', () => {
// Assert
expect(mounted).toMatchSnapshot()
})

it('updates when updating bundles array', () => {
// Arrange
const localVue = createLocalVue()
localVue.use(FluentVue)

bundleEn = new FluentBundle('en-US', {
useIsolating: false
})

bundleUk = new FluentBundle('uk-UA', {
useIsolating: false
})

const fluent = new FluentVue({
bundles: [bundleUk, bundleEn]
})

bundleEn.addResource(
new FluentResource(ftl`
link = link text
`)
)

bundleUk.addResource(
new FluentResource(ftl`
link = текст посилання
`)
)

const component = {
template: `<a v-t:link href="/foo">Fallback text</a>`
}

// Act
const mounted = mount(component, {
fluent,
localVue
})

expect(mounted).toMatchSnapshot()

fluent.bundles = [bundleEn, bundleUk]

// Assert
expect(mounted).toMatchSnapshot()
})
})
1 change: 1 addition & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"strict": true,
"sourceMap": true,
"esModuleInterop": true,
"downlevelIteration": true,
"outDir": "dist",
"typeRoots": [
"node_modules/@types"
Expand Down

0 comments on commit bfc3039

Please sign in to comment.