Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update: New Hooks API #4

Merged
merged 3 commits into from
Oct 8, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ module.exports = {
"@typescript-eslint/no-empty-function": 0,
"@typescript-eslint/no-explicit-any": 0,
"@typescript-eslint/no-unused-vars": ["error", { "varsIgnorePattern": "^_+$" }],
"@typescript-eslint/no-use-before-define": 0,
"@typescript-eslint/no-inferrable-types": 0,
"@typescript-eslint/no-use-before-define": 0,
"no-constant-condition": 0,
Expand Down
20 changes: 10 additions & 10 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
{
"name": "@pubpub/prosemirror-reactive",
"version": "0.1.10",
"version": "0.2.0",
"description": "Use reactive, stateful nodes in Prosemirror",
"main": "dist/index.js",
"devDependencies": {
"@types/jest": "^24.0.18",
"@types/node": "^12.7.4",
"@types/prosemirror-model": "^1.7.2",
"@types/prosemirror-state": "^1.2.5",
"@types/prosemirror-view": "^1.15.0",
"@types/prosemirror-model": "^1.13.2",
"@types/prosemirror-state": "^1.2.7",
"@types/prosemirror-view": "^1.19.1",
"@typescript-eslint/eslint-plugin": "^2.19.2",
"@typescript-eslint/parser": "^2.19.2",
"eslint": "^6.0.1",
Expand Down
13 changes: 5 additions & 8 deletions src/examples/schemas.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { ReactiveNodeSpec } from "../store/types";
import { Schema } from "prosemirror-model";

import { ReactiveNodeSpec } from "../store/types";
import { useDeferredNode, useState, useEffect, useTransactionState } from "..";

const doc: ReactiveNodeSpec = {
content: "block+",
};
Expand Down Expand Up @@ -70,7 +72,6 @@ export const feedMe: ReactiveNodeSpec = {

reactiveAttrs: {
report: function({ attrs }) {
const { useDeferredNode } = this;
return useDeferredNode(attrs.wantsToEatId, food => `yum, ${food.attrs.color}!`);
},
},
Expand All @@ -83,7 +84,6 @@ export const feedMeMore: ReactiveNodeSpec = {

reactiveAttrs: {
report: function({ attrs }) {
const { useDeferredNode } = this;
return useDeferredNode(
attrs.wantsToEatIds,
(first, second) => `yum, ${first.attrs.color} and ${second.attrs.color}!`
Expand All @@ -109,7 +109,6 @@ export const boxOpener: ReactiveNodeSpec = {
return node.attrs.value;
},
boxValue: function(node) {
const { useDeferredNode } = this;
return useDeferredNode(node.attrs.lookForBoxId, box => box.attrs.value);
},
},
Expand All @@ -132,7 +131,6 @@ export const sheepCounter: ReactiveNodeSpec = {

reactiveAttrs: {
report: function(node) {
const { useState, useEffect } = this;
const [sheepCount, setSheepCount] = useState(0);

useEffect(() => {
Expand All @@ -155,7 +153,7 @@ export const sheepNamer: ReactiveNodeSpec = {
},
reactiveAttrs: {
report: function(node) {
return this.useDeferredNode(node.attrs.sheepId, sheepNode => {
return useDeferredNode(node.attrs.sheepId, sheepNode => {
if (sheepNode) {
return `My sheep is named ${sheepNode.attrs.name}`;
}
Expand All @@ -168,7 +166,6 @@ export const sheepNamer: ReactiveNodeSpec = {
export const statefulSheepNamer: ReactiveNodeSpec = {
reactiveAttrs: {
report: function() {
const { useState, useEffect, useDeferredNode } = this;
const [sheepIndex, setSheepIndex] = useState(0);

useEffect(() => {
Expand All @@ -195,7 +192,7 @@ export const counter: ReactiveNodeSpec = {
},
reactiveAttrs: {
count: function() {
const counterState = this.useTransactionState(["counter"], { count: 0 });
const counterState = useTransactionState(["counter"], { count: 0 });
counterState.count++;
return counterState.count;
},
Expand Down
21 changes: 21 additions & 0 deletions src/globalHooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { UseEffect, UseRef, UseState } from "./store/attrStore";
import { Hooks, UseDeferredNode, UseReactiveMap } from "./store/types";

let currentHooks: null | Hooks = null;

export const setCurrentHooks = (hooks: Hooks) => {
currentHooks = hooks;
};

export const useDeferredNode: UseDeferredNode = (nodeIds, callback) =>
currentHooks.useDeferredNode(nodeIds, callback);

export const useDocumentState: UseReactiveMap = (path, initialState) =>
currentHooks.useDocumentState(path, initialState);

export const useTransactionState: UseReactiveMap = (path, initialState) =>
currentHooks.useTransactionState(path, initialState);

export const useState: UseState = initialValue => currentHooks.useState(initialValue);
export const useEffect: UseEffect = (fn, dependencies) => currentHooks.useEffect(fn, dependencies);
export const useRef: UseRef = initialValue => currentHooks.useRef(initialValue);
8 changes: 8 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
export * from "./plugin";
export { getReactedDoc } from "./doc";
export { addTemporaryIdsToDoc } from "./util";
export {
useState,
useEffect,
useRef,
useDeferredNode,
useTransactionState,
useDocumentState,
} from "./globalHooks";
20 changes: 6 additions & 14 deletions src/store/__tests__/attrStore.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* global it, expect, jest */
import { Node } from "prosemirror-model";

import { useState, useEffect, useRef, useDocumentState } from "../..";
import { createSchema, greeter } from "../../examples/schemas";
import { AttrStore } from "../attrStore";

Expand All @@ -10,8 +11,8 @@ const schema = createSchema({ greeter });

const testNode = Node.fromJSON(schema, { type: "greeter", attrs: { name: "world" } });

const createTestStore = (fn, globalHooks = {}, onInvalidate?) =>
new AttrStore("anything", fn, globalHooks, onInvalidate);
const createTestStore = (fn, documentHooks = {}, onInvalidate?) =>
new AttrStore("anything", fn, documentHooks as any, onInvalidate);

it("runs an attr that can access the current Node value", () => {
const attr = createTestStore(function stateCell(node) {
Expand All @@ -24,17 +25,16 @@ it("runs an attr that can access the current Node value", () => {
it("runs an attr that can access the current global hooks", () => {
const attr = createTestStore(
function stateCell() {
return this.use3();
return useDocumentState(["hey"]);
},
{ use3: () => 3 }
{ useDocumentState: ([val]) => `${val}? yep.` }
);
const result = attr.run(testNode);
expect(result).toEqual(3);
expect(result).toEqual("hey? yep.");
});

it("runs an attr with a useState call", () => {
const attr = createTestStore(function stateCell() {
const { useState } = this;
const [someState] = useState("hello!");
return someState;
});
Expand All @@ -44,7 +44,6 @@ it("runs an attr with a useState call", () => {

it("runs an attr with a useRef call", () => {
const attr = createTestStore(function stateCell() {
const { useRef } = this;
const count = useRef(-1);
count.current += 1;
return count.current;
Expand All @@ -58,7 +57,6 @@ it("runs an attr with a useRef call", () => {

it("runs an attr with a useState and a useEffect call", () => {
const attr = createTestStore(function stateCell() {
const { useState, useEffect } = this;
const [count, setCount] = useState(0);

// In a DocumentStore this would trigger an infinite loop
Expand All @@ -75,7 +73,6 @@ it("runs an attr with a useState and a useEffect call", () => {

it("runs another attr that uses both useState and useEffect", () => {
const attr = createTestStore(function() {
const { useState, useEffect } = this;
const [count, setCount] = useState(37);

useEffect(() => {
Expand All @@ -98,7 +95,6 @@ it("re-runs a useEffect hook only when its dependencies change", () => {
let b = 5;

const attr = createTestStore(function() {
const { useEffect } = this;
useEffect(() => {
callbackFn();
return teardownFn;
Expand Down Expand Up @@ -136,7 +132,6 @@ it("tears down a useEffect hook as expected", () => {
let useFirstTeardown = true;

const attr = createTestStore(function() {
const { useEffect } = this;
useEffect(() => {
return useFirstTeardown ? firstTeardown : secondTeardown;
});
Expand Down Expand Up @@ -164,7 +159,6 @@ it("invalidates when its state changes", () => {

const attr = createTestStore(
function() {
const { useEffect, useState } = this;
const [ready, setReady] = useState(false);

useEffect(() => {
Expand All @@ -187,7 +181,6 @@ it("does not invalidate when setState is called, but does not change the state",

const attr = createTestStore(
function() {
const { useEffect, useState } = this;
const [ready, setReady] = useState(false);

useEffect(() => {
Expand All @@ -210,7 +203,6 @@ it("does not invalidate after it has been destroyed", () => {

const attr = createTestStore(
function() {
const { useEffect, useState } = this;
const [ready, setReady] = useState(false);

useEffect(() => {
Expand Down
Loading