Skip to content

Commit

Permalink
chore: Add eslint and github actions for lint and build
Browse files Browse the repository at this point in the history
  • Loading branch information
omarluq committed Nov 23, 2023
1 parent 7f52103 commit 46fab51
Show file tree
Hide file tree
Showing 11 changed files with 90 additions and 16 deletions.
7 changes: 7 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
test/
public/
dist/
global-types.d.ts
*.config.js
*.config.json
*.config.ts
33 changes: 33 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
module.exports = {
"env": {
"browser": true,
"es2021": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
"overrides": [
{
"env": {
"node": true
},
"files": [
".eslintrc.{js,cjs}"
],
"parserOptions": {
"sourceType": "script"
}
}
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": [
"@typescript-eslint"
],
"rules": {
}
}
12 changes: 11 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,14 @@ jobs:
with:
node-version: 21
- run: yarn install --frozen-lockfile
- run: yarn test
- name: Build
run: yarn build
- name: Lint
run: yarn lint
- name: Test
run: yarn test
- name: Upload test report
uses: actions/upload-artifact@v3
with:
name: test-report
path: ./.jest-stare/*
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@ dist-ssr
*.sln
*.sw?
package-lock.json
yarn.lock
yarn.lock
results.xml
.jest-stare
3 changes: 3 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,7 @@ module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
testMatch: ['<rootDir>/test/**/*.test.ts'],
reporters: [
"default"
]
};
25 changes: 21 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,21 +1,38 @@
{
"name": "stimulus-store",
"private": true,
"version": "0.0.0",
"version": "0.0.1-beta",
"description": "Lightweight state management for Stimulus.js",
"main": "dist/stimulus-store.js",
"scripts": {
"build": "rollup -c --bundleConfigAsCjs",
"test": "jest"
"test": "jest --reporters default jest-stare",
"lint": "eslint .",
"lint:fix": "eslint . --fix"
},
"keywords": [
"stimulus",
"store"
],
"author": "",
"license": "ISC",
"devDependencies": {
"@hotwired/stimulus": "^3.2.2",
"@types/jest": "^29.5.10",
"@typescript-eslint/eslint-plugin": "^6.12.0",
"@typescript-eslint/parser": "^6.12.0",
"eslint": "^8.54.0",
"jest": "^29.7.0",
"jest-stare": "^2.5.1",
"prettier": "^3.1.0",
"rollup": "^4.5.1",
"rollup-plugin-commonjs": "^10.1.0",
"rollup-plugin-node-resolve": "^5.2.0",
"rollup-plugin-typescript2": "^0.36.0",
"ts-jest": "^29.1.1",
"typescript": "^5.2.2"
}
},
"jest-stare": {
"resultDir": ".jest-stare"
},
"private": false
}
1 change: 1 addition & 0 deletions report.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"numFailedTestSuites":0,"numFailedTests":0,"numPassedTestSuites":3,"numPassedTests":21,"numPendingTestSuites":0,"numPendingTests":0,"numRuntimeErrorTestSuites":0,"numTodoTests":0,"numTotalTestSuites":3,"numTotalTests":21,"openHandles":[],"snapshot":{"added":0,"didUpdate":false,"failure":false,"filesAdded":0,"filesRemoved":0,"filesRemovedList":[],"filesUnmatched":0,"filesUpdated":0,"matched":0,"total":0,"unchecked":0,"uncheckedKeysByFile":[],"unmatched":0,"updated":0},"startTime":1700710936337,"success":true,"testResults":[{"assertionResults":[{"ancestorTitles":["camelize"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"camelize should correctly camelize testString","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"should correctly camelize testString"},{"ancestorTitles":["camelize"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"camelize should correctly camelize TestString","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"should correctly camelize TestString"},{"ancestorTitles":["camelize"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"camelize should correctly camelize testString","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"should correctly camelize testString"},{"ancestorTitles":["camelize"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"camelize should correctly camelize TestString","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"should correctly camelize TestString"}],"endTime":1700710936966,"message":"","name":"/Users/oluqman/Desktop/dev/stimulus-store/test/camelize.test.ts","startTime":1700710936363,"status":"passed","summary":""},{"assertionResults":[{"ancestorTitles":["useStore"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"useStore should subscribe to stores and call update methods on value changes","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"should subscribe to stores and call update methods on value changes"},{"ancestorTitles":["useStore"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"useStore should allow direct access to store values on the controller","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"should allow direct access to store values on the controller"},{"ancestorTitles":["useStore"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"useStore should allow direct access to store instances on the controller","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"should allow direct access to store instances on the controller"},{"ancestorTitles":["useStore"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"useStore should clean up subscriptions when controller disconnects","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"should clean up subscriptions when controller disconnects"},{"ancestorTitles":["useStore"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"useStore should add a getter for the store value to the controller","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"should add a getter for the store value to the controller"},{"ancestorTitles":["useStore"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"useStore should add a getter for the store instance to the controller","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"should add a getter for the store instance to the controller"},{"ancestorTitles":["useStore"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"useStore should add an update method to the controller","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"should add an update method to the controller"},{"ancestorTitles":["useStore"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"useStore should notify each controller when the shared store's value is updated by any controller","invocations":1,"location":null,"numPassingAsserts":6,"retryReasons":[],"status":"passed","title":"should notify each controller when the shared store's value is updated by any controller"},{"ancestorTitles":["useStore"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"useStore should call the callback with the current value when a function is passed to set","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"status":"passed","title":"should call the callback with the current value when a function is passed to set"},{"ancestorTitles":["useStore"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"useStore should update the store's value with the return value of the callback","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"should update the store's value with the return value of the callback"}],"endTime":1700710937008,"message":"","name":"/Users/oluqman/Desktop/dev/stimulus-store/test/useStore.test.ts","startTime":1700710936969,"status":"passed","summary":""},{"assertionResults":[{"ancestorTitles":["Store"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"Store should initialize with the correct value","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"should initialize with the correct value"},{"ancestorTitles":["Store"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"Store should update the value correctly","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"should update the value correctly"},{"ancestorTitles":["Store"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"Store should notify subscribers when value changes","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"should notify subscribers when value changes"},{"ancestorTitles":["Store"],"duration":1,"failureDetails":[],"failureMessages":[],"fullName":"Store should stop notifying unsubscribed callbacks","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"should stop notifying unsubscribed callbacks"},{"ancestorTitles":["Store"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"Store should not notify subscribers when value is the same","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"should not notify subscribers when value is the same"},{"ancestorTitles":["Store"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"Store should not notify subscribers when filter returns false","invocations":1,"location":null,"numPassingAsserts":1,"retryReasons":[],"status":"passed","title":"should not notify subscribers when filter returns false"},{"ancestorTitles":["Store"],"duration":0,"failureDetails":[],"failureMessages":[],"fullName":"Store should call the callback with the current value when a function is passed to set","invocations":1,"location":null,"numPassingAsserts":2,"retryReasons":[],"status":"passed","title":"should call the callback with the current value when a function is passed to set"}],"endTime":1700710937052,"message":"","name":"/Users/oluqman/Desktop/dev/stimulus-store/test/store.test.ts","startTime":1700710937015,"status":"passed","summary":""}],"wasInterrupted":false}
2 changes: 1 addition & 1 deletion src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export class Store<T> {

private notifySubscribers(options: NotifySubscriberOptions) {
Array.from(this.subscribers)
.filter(_ => options.filter(this.value))
.filter(() => options.filter(this.value))
.forEach(callback => callback(this.value))
}
}
5 changes: 3 additions & 2 deletions src/storeController.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import type { Controller } from "@hotwired/stimulus"
import type { Store } from './store';

export interface StoreController extends Controller {
export interface StoreController<T> extends Controller {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
[key: string]: any;
constructor: {
stores?: Store<any>[];
stores?: Store<T>[];
};
}
8 changes: 4 additions & 4 deletions src/useStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,18 +42,18 @@ import type { Store } from './store';
import type { StoreController } from './storeController'; // Adjust the path as needed
import { camelize } from './utils/camelize';

export function useStore(controller: StoreController) {
const stores: Store<any>[] = controller.constructor.stores || [];
export function useStore<T>(controller: StoreController<T>) {
const stores: Store<T>[] = controller.constructor.stores || [];
const unsubscribeFunctions: (() => void)[] = [];

stores.forEach((store) => {
const storeName: string = store.name;
const camelizedName = camelize(storeName);
const onStoreUpdateMethodName = `on${camelize(storeName, true)}Update`;
const onStoreUpdateMethod: (value: any) => void = controller[onStoreUpdateMethodName];
const onStoreUpdateMethod = controller[onStoreUpdateMethodName] as (value: T) => void;

if (onStoreUpdateMethod) {
const updateMethod: (value: any) => void = value => {
const updateMethod: (value: T) => void = value => {
onStoreUpdateMethod.call(controller, value);
};

Expand Down
6 changes: 3 additions & 3 deletions test/useStore.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useStore } from '../src/useStore';
import type { StoreController } from '../src/storeController';

describe('useStore', () => {
let mockController: StoreController;
let mockController: StoreController<any>;
let testStore: Store<number>;

beforeEach(() => {
Expand All @@ -19,7 +19,7 @@ describe('useStore', () => {
scope: jest.fn(),
element: jest.fn(),
// Add the other missing properties here...
} as unknown as StoreController;
} as unknown as StoreController<any>;

useStore(mockController);
});
Expand Down Expand Up @@ -72,7 +72,7 @@ describe('useStore', () => {
scope: jest.fn(),
element: jest.fn(),
// Add the other missing properties here...
} as unknown as StoreController;
} as unknown as StoreController<any>;
// Assume that the controllers have a method to update the store's value
useStore(mockController2);
mockController.updateTestStore = (value: any) => testStore.set(value);
Expand Down

0 comments on commit 46fab51

Please sign in to comment.