Skip to content
This repository has been archived by the owner on Mar 23, 2018. It is now read-only.

Commit

Permalink
fix(rule): fix cache mechanism
Browse files Browse the repository at this point in the history
  • Loading branch information
azu committed Mar 18, 2018
1 parent ce0aa4e commit 0ce4bed
Show file tree
Hide file tree
Showing 9 changed files with 135 additions and 61 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
"dependencies": {
"@types/url-join": "^0.8.2",
"debug": "^3.1.0",
"fetch-ponyfill": "^5.0.1",
"fetch-ponyfill": "^6.0.0",
"localstorage-ponyfill": "^1.0.1",
"proofdict": "^1.2.1",
"proofdict-tester": "^1.0.0",
Expand Down
36 changes: 34 additions & 2 deletions src/create-tester.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
// MIT © 2017 azu
"use strict";
import { MODE } from "./mode";
import { storage } from "./dictionary-storage";

const { ProofdictTester } = require("proofdict-tester");
let currentTester = null;
let checkedLastTime = -1;
Expand All @@ -8,10 +11,11 @@ let checkedLastTime = -1;
* @param {*} dictionary
* @param {string[]} whitelistTags
* @param {string[]} blacklistTags
* @param {boolean} disableTesterCache
* @returns {ProofdictTester}
*/
export const createTester = ({ lastUpdated, dictionary, whitelistTags, blacklistTags }) => {
if (currentTester === null && checkedLastTime < lastUpdated) {
export const createTester = ({ lastUpdated, dictionary, whitelistTags, blacklistTags, disableTesterCache }) => {
if (disableTesterCache || (currentTester === null && checkedLastTime < lastUpdated)) {
checkedLastTime = lastUpdated;
currentTester = new ProofdictTester({
dictionary,
Expand All @@ -22,3 +26,31 @@ export const createTester = ({ lastUpdated, dictionary, whitelistTags, blacklist
}
return currentTester;
};


/**
* @param options
* @param {string} mode
* @returns {*}
*/
export const getDictionary = (options, mode) => {
// prefer `dictionary` option
if (options.proofdict !== undefined) {
return options.proofdict;
}
let proofDictData;
// NETWORK
if (mode === MODE.NETWORK) {
try {
const cachedProofdict = storage.getItem("proofdict");
proofDictData = JSON.parse(cachedProofdict);
} catch (error) {
storage.removeItem("proofdict");
}
}
// LOCAL
if (mode === MODE.LOCAL) {
// TODO: not implemented
}
return proofDictData;
};
24 changes: 24 additions & 0 deletions src/dictionary-storage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// MIT © 2018 azu
"use strict";
const { createLocalStorage } = require("localstorage-ponyfill");


class Storage {
constructor() {
this.localStorage = createLocalStorage();
}

getItem(name, defaultValue) {
return this.localStorage.getItem(name, defaultValue);
}

setItem(name, value) {
return this.localStorage.setItem(name, value);
};

removeItem(name) {
return this.localStorage.removeItem(name);
}
}

export const storage = new Storage();
9 changes: 9 additions & 0 deletions src/mode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// MIT © 2018 azu
"use strict";
/**
* @type {{LOCAL: string, NETWORK: string}}
*/
export const MODE = {
LOCAL: "LOCAL",
NETWORK: "NETWORK"
};
2 changes: 1 addition & 1 deletion src/proofdict-repo-util.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export function getDictJSONURL(options) {
if (typeof options.dictURL === "object" && typeof options.dictURL.jsonAPI === "string") {
return options.dictURL.jsonAPI;
}
return urlJoin(options.dictURL, "dict.json");
return urlJoin(options.dictURL, "dictionary.json");
}

/**
Expand Down
62 changes: 21 additions & 41 deletions src/textlint-rule-proofdict.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
// MIT © 2017 azu
"use strict";
const debug = require("debug")("textlint-rule-proofdict");
const { createLocalStorage } = require("localstorage-ponyfill");
const { RuleHelper } = require("textlint-rule-helper");
import { createTester } from "./create-tester";
import { createTester, getDictionary } from "./create-tester";
import { fetchProofdict } from "./fetch-proofdict";
import { getDictJSONURL, getRuleURL } from "./proofdict-repo-util";
import { MODE } from "./mode";
import { storage } from "./dictionary-storage";

const DefaultOptions = {
// If you want to use live-proofdict
Expand All @@ -28,16 +29,11 @@ const DefaultOptions = {
"blacklistTags": [],
// For testing
// set you proofdict json object
"proofdict": undefined
"proofdict": undefined,
// Disable cache for tester
"disableProofdictTesterCache": false
};

/**
* @type {{LOCAL: string, NETWORK: string}}
*/
const MODE = {
LOCAL: "LOCAL",
NETWORK: "NETWORK"
};
const reporter = (context, options = DefaultOptions) => {
const helper = new RuleHelper(context);
const { Syntax, RuleError, report, getSource, fixer } = context;
Expand All @@ -52,24 +48,28 @@ Please set dictURL or dictPath to .textlintrc.`))
const mode = options.dictURL ? MODE.NETWORK : MODE.LOCAL;
const whitelistTags = Array.isArray(options.whitelistTags) ? options.whitelistTags : DefaultOptions.whitelistTags;
const blacklistTags = Array.isArray(options.blacklistTags) ? options.blacklistTags : DefaultOptions.blacklistTags;
const disableTesterCache = options.disableProofdictTesterCache !== undefined
? options.disableProofdictTesterCache
: DefaultOptions.disableProofdictTesterCache;
const autoUpdateInterval = options.autoUpdateInterval !== undefined
? options.autoUpdateInterval
: DefaultOptions.autoUpdateInterval;
const localStorage = createLocalStorage();
? options.autoUpdateInterval
: DefaultOptions.autoUpdateInterval;
const targetNodes = [];
const addQueue = node => targetNodes.push(node);
let promiseQueue = null;
return {
[Syntax.Document]() {
// default: 0
const lastUpdated = Number(localStorage.getItem("proofdict-lastUpdated", "0"));
const isExpired = lastUpdated + autoUpdateInterval < Date.now();
const lastUpdated = Number(storage.getItem("proofdict-lastUpdated", "-1"));
const isExpired = lastUpdated <= 0
? true
: Date.now() - lastUpdated > autoUpdateInterval;
if (mode === MODE.NETWORK && isExpired) {
const jsonAPIURL = getDictJSONURL(options);
promiseQueue = fetchProofdict({ URL: jsonAPIURL })
.then(dictionary => {
localStorage.setItem("proofdict", JSON.stringify(dictionary));
localStorage.setItem("proofdict-lastUpdated", Date.now());
storage.setItem("proofdict", JSON.stringify(dictionary));
storage.setItem("proofdict-lastUpdated", Date.now());
})
.catch(error => {
debug("Fetch is failed", error);
Expand All @@ -84,34 +84,14 @@ Please set dictURL or dictPath to .textlintrc.`))
},
[`${Syntax.Document}:exit`]() {
return promiseQueue.then(() => {
const getDict = (options) => {
// prefer `dictionary` option
if (options.proofdict !== undefined) {
return options.proofdict;
}
let proofDictData;
// NETWORK
if (options.dictURL) {
try {
const cachedProofdict = localStorage.getItem("proofdict");
proofDictData = JSON.parse(cachedProofdict);
} catch (error) {
localStorage.removeItem("proofdict");
}
}
// LOCAL
if (options.dictPath) {
// TODO: not implemented
}
return proofDictData;
};
const dictionary = getDict(options);
const lastUpdated = Number(localStorage.getItem("proofdict-lastUpdated", "0"));
const dictionary = getDictionary(options, mode);
const lastUpdated = Number(storage.getItem("proofdict-lastUpdated", "0"));
const tester = createTester({
dictionary,
lastUpdated,
whitelistTags,
blacklistTags
blacklistTags,
disableTesterCache
});
// check
const promises = targetNodes.map(node => {
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/proofdict.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@
"noun"
]
}
]
]
53 changes: 41 additions & 12 deletions test/textlint-rule-proofdict-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,35 @@ const TextLintTester = require("textlint-tester");
const tester = new TextLintTester();
// rule
import rule from "../src/textlint-rule-proofdict";
// IN testing , disable tester cache
const disableProofdictTesterCache = true;
const defaultOptions = {
disableProofdictTesterCache,
proofdict: require("./fixtures/proofdict.json")
};
// ruleName, rule, { valid, invalid }
tester.run("proofdict", rule, {
valid: [
{
text: "jQuery",
options: {
proofdict: require("./fixtures/proofdict.json")
}
options: defaultOptions
},
{
text: "WebKit",
options: {
proofdict: require("./fixtures/proofdict.json")
}
options: defaultOptions
},
{
text: "WebKit",
options: {
proofdict: require("./fixtures/proofdict.json")
}
options: defaultOptions
},
],
invalid: [
{
text: "texlint check your texts.\n" + "jquery is libray.\n",
output: "texlint check your texts.\n" + "jQuery is libray.\n",
options: {
dictURL: "https://proofdict.github.io/proof-dictionary/"
dictURL: "https://proofdict.github.io/proof-dictionary/",
disableProofdictTesterCache
},
errors: [
{
Expand All @@ -44,7 +45,8 @@ tester.run("proofdict", rule, {
text: "jquery",
output: "jQuery",
options: {
dictURL: "https://proofdict.github.io/proof-dictionary/"
dictURL: "https://proofdict.github.io/proof-dictionary/",
disableProofdictTesterCache
},
errors: [
{
Expand All @@ -59,7 +61,34 @@ tester.run("proofdict", rule, {
text: "This is webkit.",
output: "This is WebKit.",
options: {
proofdict: require("./fixtures/proofdict.json")
proofdict: [
{
"id": "01BQ92YZ6QR8RJKA5Y8W2F9NMY",
"description": "Reference https://webkit.org/",
"expected": "WebKit",
"patterns": [
"/webkit/i"
],
"specs": [
{
"from": "これはwebkitです",
"to": "これはWebKitです"
},
{
"from": "XXXwebkit",
"to": "XXXwebkit"
},
{
"from": "node-webkit",
"to": "node-webkit"
}
],
"tags": [
"noun"
]
}
],
disableProofdictTesterCache
},
errors: [
{
Expand Down
6 changes: 3 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1139,9 +1139,9 @@ fetch-ponyfill@^4.1.0:
dependencies:
node-fetch "~1.7.1"

fetch-ponyfill@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/fetch-ponyfill/-/fetch-ponyfill-5.0.1.tgz#2789ec179c1de357f60f9fd49e154a8b3fd8cd1b"
fetch-ponyfill@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/fetch-ponyfill/-/fetch-ponyfill-6.0.0.tgz#1809503d4e3f966920708bb296114e1b69c0c477"
dependencies:
node-fetch "~2.0.0"

Expand Down

0 comments on commit 0ce4bed

Please sign in to comment.