Skip to content
This repository has been archived by the owner on Aug 30, 2022. It is now read-only.

Commit

Permalink
Merge pull request #122 from latitudegames/spell-api-integration
Browse files Browse the repository at this point in the history
Spell api integration
  • Loading branch information
michaelsharpe authored Oct 13, 2021
2 parents e762c20 + 1f99a86 commit 8be49d4
Show file tree
Hide file tree
Showing 29 changed files with 379 additions and 180 deletions.
1 change: 0 additions & 1 deletion client/.env.example
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
REACT_APP_GAME_KEY=8144b347-8437-415d-b276-aac68c83b1dc
REACT_APP_API_URL=https://latitude-game-api.herokuapp.com
#REACT_APP_API_URL=http://localhost:8000
EXTEND_ESLINT = true
29 changes: 13 additions & 16 deletions client/src/contexts/EditorProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import { useLazyGetSpellQuery, Spell } from '../state/spells'
import LoadingScreen from '../features/common/LoadingScreen/LoadingScreen'
import { MyNode } from '../features/common/Node/Node'
import gridimg from '../grid.png'
import { useSpell } from './SpellProvider'
import { usePubSub } from './PubSubProvider'
import { useRete, ReteContext } from './ReteProvider'
// import { ThothTab } from './TabManagerProvider'
Expand Down Expand Up @@ -41,7 +40,7 @@ const Context = createContext({
setEditor: (editor: any) => {},
getNodeMap: () => {},
getNodes: () => {},
loadGraph: (graph: any) => {},
loadChain: (chain: any) => {},
setContainer: () => {},
undo: () => {},
redo: () => {},
Expand All @@ -52,7 +51,7 @@ export const useEditor = () => useContext(Context)
const EditorProvider = ({ children }) => {
const [editor, setEditorState] = useState({
components: [],
loadGraph: (graph: any) => {},
loadGraph: (chain: any) => {},
})
const editorRef = useRef({
trigger: (event: string) => {},
Expand All @@ -70,8 +69,6 @@ const EditorProvider = ({ children }) => {
}

const buildEditor = async (container, _spell, tab, thoth) => {
// copy spell in case it is read only
const spell = JSON.parse(JSON.stringify(_spell))
// eslint-disable-next-line no-console
const newEditor = await initEditor({
container,
Expand All @@ -86,7 +83,11 @@ const EditorProvider = ({ children }) => {
// set editor to the map
setEditor(newEditor)

if (tab.type === 'spell') newEditor.loadGraph(spell.graph)
if (tab.type === 'spell') {
// copy spell in case it is read onl
const spell = JSON.parse(JSON.stringify(_spell))
newEditor.loadGraph(spell.chain)
}

if (tab.type === 'module') {
const moduleDoc = await thoth.getModule(tab.module)
Expand Down Expand Up @@ -118,7 +119,7 @@ const EditorProvider = ({ children }) => {
return editor && Object.fromEntries(editor.components)
}

const loadGraph = graph => {
const loadChain = graph => {
editor.loadGraph(graph)
}

Expand All @@ -134,7 +135,7 @@ const EditorProvider = ({ children }) => {
buildEditor,
getNodeMap,
getNodes,
loadGraph,
loadChain,
setEditor,
getEditor,
undo,
Expand All @@ -149,17 +150,17 @@ const RawEditor = ({ tab, children }) => {
const [getSpell, { data: spell, isLoading }] = useLazyGetSpellQuery()
const [loaded, setLoaded] = useState(false)
const { buildEditor } = useEditor()
const { getCurrentGameState, updateCurrentGameState } = useSpell()
// This will be the main interface between thoth and rete
const reteInterface = useRete()

useEffect(() => {
if (!tab) return

getSpell(tab.spell)
if (tab?.spell) getSpell(tab.spell)
}, [tab])

if (isLoading || !tab || !spell) return <LoadingScreen />
if (!tab || (tab.type === 'spell' && (isLoading || !spell)))
return <LoadingScreen />

return (
<>
Expand All @@ -180,11 +181,7 @@ const RawEditor = ({ tab, children }) => {
<div
ref={el => {
if (el && !loaded) {
buildEditor(el, spell, tab, {
...reteInterface,
getCurrentGameState,
updateCurrentGameState,
})
buildEditor(el, spell, tab, reteInterface)
setLoaded(true)
}
}}
Expand Down
2 changes: 1 addition & 1 deletion client/src/contexts/ModuleProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ const ModuleProvider = ({ children }) => {

const getSpellModules = async spell => {
// should actually look for spells that have a data.module key set to a string
const moduleNames = Object.values(spell.graph.nodes)
const moduleNames = Object.values(spell.chain.nodes)
.filter((n: any) => n.name === 'Module')
.map((n: any) => n.data.name)

Expand Down
24 changes: 24 additions & 0 deletions client/src/contexts/ReteProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { EngineContext } from '@latitudegames/thoth-core'
import { useContext, createContext } from 'react'
import { useDispatch } from 'react-redux'

import { postEnkiCompletion } from '../services/game-api/enki'
import { completion as _completion } from '../services/game-api/text'
import { selectGameStateBySpellId, updateGameState } from '../state/gameState'
import { store } from '../state/store'
import { invokeInference } from '../utils/huggingfaceHelper'
import { useDB } from './DatabaseProvider'
import { usePubSub } from './PubSubProvider'
Expand Down Expand Up @@ -42,6 +45,8 @@ const Context = createContext({
getGameState: () => {},
setGameState: () => {},
getModules: async () => {},
getCurrentGameState: () => ({} as Record<string, unknown>),
updateCurrentGameState: () => new Promise(() => {}) as Promise<void>,
completion: _completion,
enkiCompletion: async (): Promise<{ outputs: string[] }> =>
await new Promise(resolve => {
Expand All @@ -57,6 +62,7 @@ export const useRete = () => useContext(Context)

const ReteProvider = ({ children, tab }) => {
const { events, publish, subscribe } = usePubSub()
const dispatch = useDispatch()
const {
models: { spells, modules },
} = useDB()
Expand Down Expand Up @@ -135,6 +141,22 @@ const ReteProvider = ({ children, tab }) => {
publish($TEXT_EDITOR_CLEAR(tab.id))
}

const getCurrentGameState = () => {
const currentGameState = selectGameStateBySpellId(
store.getState().gameState,
tab.spell
)
return currentGameState?.state
}

const updateCurrentGameState = update => {
const newState = {
spellId: tab.spell,
state: update,
}
dispatch(updateGameState(newState))
}

const publicInterface = {
onInspector,
onAddModule,
Expand All @@ -148,6 +170,8 @@ const ReteProvider = ({ children, tab }) => {
completion,
enkiCompletion,
huggingface,
getCurrentGameState,
updateCurrentGameState,
...modules,

// going to need to manuall create theses
Expand Down
35 changes: 32 additions & 3 deletions client/src/database/models/moduleModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,6 @@ const loadModuleModel = db => {
const updateModule = async (moduleName: string, update: object) => {
const module = await getModule(moduleName)

// eslint-disable-next-line
console.log('module', module)

const updatedModule = await module.atomicUpdate(oldData => {
return {
...oldData,
Expand Down Expand Up @@ -68,6 +65,37 @@ const loadModuleModel = db => {
return await db.modules.insert(newModule)
}

const getNestedModules = async (moduleNames: string[]) => {
const moduleDocs = await Promise.all(
moduleNames.map(moduleName => getModule(moduleName))
)
if (moduleDocs.length === 0) return []
const modules = moduleDocs.filter(Boolean).map(module => module.toJSON())
const nestedModules = await Promise.all(
modules.map(async module => {
const nestedModuleNames = Object.values(module.data.nodes)
.filter((n: any) => n.data.module)
.map((n: any) => n.data.module)
if (nestedModuleNames.length === 0) {
return []
} else {
const nextModuleLayer = await getNestedModules(nestedModuleNames)
return nextModuleLayer.flat()
}
})
)
return modules.concat(nestedModules.flat())
}

const getSpellModules = async spell => {
const moduleNames = Object.values(spell.chain.nodes)
.filter((n: any) => n.data.module)
.map((n: any) => n.data.module)

const modules = await getNestedModules(moduleNames)
return modules
}

return {
insert,
getModules,
Expand All @@ -76,6 +104,7 @@ const loadModuleModel = db => {
updateModule,
findOneModule,
updateOrCreate,
getSpellModules,
}
}
export default loadModuleModel
8 changes: 6 additions & 2 deletions client/src/features/StartScreen/components/CreateNew.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,16 @@ const CreateNew = () => {
const onCreate = async () => {
const placeholderName = uniqueNamesGenerator(customConfig)
const { data: spell } = await newSpell({
graph: defaultGraph,
chain: defaultGraph,
name: placeholderName,
})

await clearTabs()
await openTab({ name: spell.name, spellId: spell.name, type: 'spell' })
await openTab({
name: placeholderName,
spellId: placeholderName,
type: 'spell',
})
setLocation('/thoth')
}

Expand Down
7 changes: 6 additions & 1 deletion client/src/features/Thoth/Thoth.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,12 @@ const Thoth = ({ empty }) => {
<TabLayout>
{!empty &&
tabs.map((tab, i) => (
<Workspace tab={tab} key={`${i}-${tab.name}`} appPubSub={pubSub} />
<Workspace
tab={tab}
tabs={tabs}
key={`${i}-${tab.name}`}
appPubSub={pubSub}
/>
))}
</TabLayout>
)
Expand Down
21 changes: 15 additions & 6 deletions client/src/features/Thoth/components/EditorWindow/Deployment.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,23 @@ const DeploymentView = ({ open, setOpen, spellId }) => {

const [deploySpell] = useDeploySpellMutation()
const spell = useSelector(state => selectSpellById(state, spellId))
const { data: deployments, isLoading } = useGetDeploymentsQuery(
spell?.name || ''
)
const name = spell?.name as string
const { data: deployments, isLoading } = useGetDeploymentsQuery(name, {
skip: !spell?.name,
})

const deploy = message => {
if (!spell) return
deploySpell({ spellId: spell.name, message })
enqueueSnackbar('Spell deployed', { variant: 'success' })
}

const buildUrl = version => {
return encodeURI(
`${process.env.REACT_APP_API_URL}/games/spells/${spellId}/${version}`
)
}

const copy = url => {
const el = document.createElement('textarea')
el.value = url
Expand Down Expand Up @@ -127,10 +134,12 @@ const DeploymentView = ({ open, setOpen, spellId }) => {
>
<Input
style={{ flex: 1 }}
value={deploy.url}
readonly
value={buildUrl(deploy.version)}
readOnly
/>
<button onClick={() => copy(deploy.url)}>copy</button>
<button onClick={() => copy(buildUrl(deploy.version))}>
copy
</button>
</div>
<p> Change notes </p>
<Panel
Expand Down
4 changes: 2 additions & 2 deletions client/src/features/Thoth/components/EventHandler.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ const EventHandler = ({ pubSub, tab }) => {

const saveSpell = async () => {
const currentSpell = spellRef.current
const graph = serialize(currentSpell)
const chain = serialize(currentSpell)

await saveSpellMutation({ ...currentSpell, graph })
await saveSpellMutation({ ...currentSpell, chain })
}

const createStateManager = () => {
Expand Down
Loading

0 comments on commit 8be49d4

Please sign in to comment.