|  |  | @ -2,14 +2,14 @@ package main | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | import ( |  |  |  | import ( | 
			
		
	
		
		
			
				
					
					|  |  |  |   "fmt" |  |  |  |   "fmt" | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   "io" | 
			
		
	
		
		
			
				
					
					|  |  |  |   "reflect" |  |  |  |   "reflect" | 
			
		
	
		
		
			
				
					
					|  |  |  |   "errors" |  |  |  |   "errors" | 
			
		
	
		
		
			
				
					
					|  |  |  |   "sync" |  |  |  |   "sync" | 
			
		
	
		
		
			
				
					
					|  |  |  |   "net/http" |  |  |  |   "net/http" | 
			
		
	
		
		
			
				
					
					|  |  |  |   "io" |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   "github.com/graphql-go/graphql" |  |  |  |   "github.com/graphql-go/graphql" | 
			
		
	
		
		
			
				
					
					|  |  |  |   "github.com/graphql-go/handler" |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   "context" |  |  |  |   "context" | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   "encoding/json" | 
			
		
	
		
		
			
				
					
					|  |  |  | ) |  |  |  | ) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | // Resources propagate update up to multiple parents, and not downwards
 |  |  |  | // Resources propagate update up to multiple parents, and not downwards
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -260,76 +260,6 @@ func NewResource(name string, description string, children []Resource) * BaseRes | 
			
		
	
		
		
			
				
					
					|  |  |  |   return &resource |  |  |  |   return &resource | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | const graphiql_string string = ` |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | <!-- |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  *  Copyright (c) 2021 GraphQL Contributors |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  *  All rights reserved. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  * |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  *  This source code is licensed under the license found in the |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  *  LICENSE file in the root directory of this source tree. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | --> |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | <!DOCTYPE html> |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | <html lang="en"> |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   <head> |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     <title>GraphiQL</title> |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     <style> |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       body { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         height: 100%; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         margin: 0; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         width: 100%; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         overflow: hidden; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       #graphiql { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         height: 100vh; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     </style> |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     <!-- |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       This GraphiQL example depends on Promise and fetch, which are available in |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       modern browsers, but can be "polyfilled" for older browsers. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       GraphiQL itself depends on React DOM. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       If you do not want to rely on a CDN, you can host these files locally or |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       include them directly in your favored resource bundler. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     --> |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     <script |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       crossorigin |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       src="https://unpkg.com/react@18/umd/react.development.js" |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     ></script> |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     <script |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       crossorigin |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     ></script> |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     <!-- |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       These two files can be found in the npm module, however you may wish to |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       copy them directly into your environment, or perhaps include them in your |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       favored resource bundler. |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |      --> |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     <link rel="stylesheet" href="https://unpkg.com/graphiql/graphiql.min.css" /> |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   </head> |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   <body> |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     <div id="graphiql">Loading...</div> |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     <script |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       src="https://unpkg.com/graphiql/graphiql.min.js" |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       type="application/javascript" |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     ></script> |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     <script> |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       const root = ReactDOM.createRoot(document.getElementById('graphiql')); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       root.render( |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         React.createElement(GraphiQL, { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |           fetcher: GraphiQL.createFetcher({ |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |             url: 'http://localhost:8080/gql',
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |           }), |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |           defaultEditorToolsVisibility: true, |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         }), |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       ); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     </script> |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |   </body> |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | </html> |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | ` |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | type GQLServer struct { |  |  |  | type GQLServer struct { | 
			
		
	
		
		
			
				
					
					|  |  |  |   BaseResource |  |  |  |   BaseResource | 
			
		
	
		
		
			
				
					
					|  |  |  |   abort chan error |  |  |  |   abort chan error | 
			
		
	
	
		
		
			
				
					|  |  | @ -339,7 +269,7 @@ type GQLServer struct { | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | func NewGQLServer(listen string) * GQLServer { |  |  |  | func NewGQLServer(listen string) * GQLServer { | 
			
		
	
		
		
			
				
					
					|  |  |  |   server := &GQLServer{ |  |  |  |   server := &GQLServer{ | 
			
		
	
		
		
			
				
					
					|  |  |  |     BaseResource: NewBaseResource("GQL Connection", "Connection to a GQL server", []Resource{}), |  |  |  |     BaseResource: NewBaseResource("GQL Server", "graphql server for event signals", []Resource{}), | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     listen: listen, |  |  |  |     listen: listen, | 
			
		
	
		
		
			
				
					
					|  |  |  |     abort: make(chan error, 1), |  |  |  |     abort: make(chan error, 1), | 
			
		
	
		
		
			
				
					
					|  |  |  |     gql_channel: make(chan error, 1), |  |  |  |     gql_channel: make(chan error, 1), | 
			
		
	
	
		
		
			
				
					|  |  | @ -367,12 +297,24 @@ func GQLEventChildren(p graphql.ResolveParams) (interface{}, error) { | 
			
		
	
		
		
			
				
					
					|  |  |  |   return nil, errors.New("Failed to cast source to event") |  |  |  |   return nil, errors.New("Failed to cast source to event") | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | func (server * GQLServer) Schema() * graphql.Schema { |  |  |  | var gql_list_event * graphql.List = nil | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   valid_events := map[reflect.Type]*graphql.Object{} |  |  |  | func GQLListEvent() * graphql.List { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   gql_interface_event := graphql.NewInterface(graphql.InterfaceConfig{ |  |  |  |   if gql_list_event == nil { | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     gql_list_event = graphql.NewList(GQLInterfaceEvent()) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   return gql_list_event | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | var gql_interface_event * graphql.Interface = nil | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | func GQLInterfaceEvent() * graphql.Interface { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   if gql_interface_event == nil { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     gql_interface_event = graphql.NewInterface(graphql.InterfaceConfig{ | 
			
		
	
		
		
			
				
					
					|  |  |  |       Name: "Event", |  |  |  |       Name: "Event", | 
			
		
	
		
		
			
				
					
					|  |  |  |     Fields: graphql.Fields{}, |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object { |  |  |  |       ResolveType: func(p graphql.ResolveTypeParams) *graphql.Object { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         valid_events, ok := p.Context.Value("valid_events").(map[reflect.Type]*graphql.Object) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         if ok == false { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           return nil | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |         for key, value := range(valid_events) { |  |  |  |         for key, value := range(valid_events) { | 
			
		
	
		
		
			
				
					
					|  |  |  |           if reflect.TypeOf(p.Value) == key { |  |  |  |           if reflect.TypeOf(p.Value) == key { | 
			
		
	
		
		
			
				
					
					|  |  |  |             return value |  |  |  |             return value | 
			
		
	
	
		
		
			
				
					|  |  | @ -380,19 +322,32 @@ func (server * GQLServer) Schema() * graphql.Schema { | 
			
		
	
		
		
			
				
					
					|  |  |  |         } |  |  |  |         } | 
			
		
	
		
		
			
				
					
					|  |  |  |         return nil |  |  |  |         return nil | 
			
		
	
		
		
			
				
					
					|  |  |  |       }, |  |  |  |       }, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       Fields: graphql.Fields{}, | 
			
		
	
		
		
			
				
					
					|  |  |  |     }) |  |  |  |     }) | 
			
		
	
		
		
			
				
					
					|  |  |  |   gql_type_event_list := graphql.NewList(gql_interface_event) |  |  |  | 
 | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if gql_list_event == nil { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       gql_list_event = graphql.NewList(GQLInterfaceEvent()) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     gql_interface_event.AddFieldConfig("ID", &graphql.Field{ |  |  |  |     gql_interface_event.AddFieldConfig("ID", &graphql.Field{ | 
			
		
	
		
		
			
				
					
					|  |  |  |       Type: graphql.String, |  |  |  |       Type: graphql.String, | 
			
		
	
		
		
			
				
					
					|  |  |  |     }) |  |  |  |     }) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     gql_interface_event.AddFieldConfig("Children", &graphql.Field{ |  |  |  |     gql_interface_event.AddFieldConfig("Children", &graphql.Field{ | 
			
		
	
		
		
			
				
					
					|  |  |  |     Type: gql_type_event_list, |  |  |  |       Type: gql_list_event, | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     }) |  |  |  |     }) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   return gql_interface_event | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | func (server * GQLServer) Handler() func(http.ResponseWriter, *http.Request) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   valid_events := map[reflect.Type]*graphql.Object{} | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   gql_type_base_event := graphql.NewObject(graphql.ObjectConfig{ |  |  |  |   gql_type_base_event := graphql.NewObject(graphql.ObjectConfig{ | 
			
		
	
		
		
			
				
					
					|  |  |  |     Name: "BaseEvent", |  |  |  |     Name: "BaseEvent", | 
			
		
	
		
		
			
				
					
					|  |  |  |     Interfaces: []*graphql.Interface{ |  |  |  |     Interfaces: []*graphql.Interface{ | 
			
		
	
		
		
			
				
					
					|  |  |  |       gql_interface_event, |  |  |  |       GQLInterfaceEvent(), | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     }, |  |  |  |     }, | 
			
		
	
		
		
			
				
					
					|  |  |  |     IsTypeOf: func(p graphql.IsTypeOfParams) bool { |  |  |  |     IsTypeOf: func(p graphql.IsTypeOfParams) bool { | 
			
		
	
		
		
			
				
					
					|  |  |  |       _, ok := p.Value.(*BaseEvent) |  |  |  |       _, ok := p.Value.(*BaseEvent) | 
			
		
	
	
		
		
			
				
					|  |  | @ -403,27 +358,17 @@ func (server * GQLServer) Schema() * graphql.Schema { | 
			
		
	
		
		
			
				
					
					|  |  |  |   valid_events[reflect.TypeOf((*BaseEvent)(nil))] = gql_type_base_event |  |  |  |   valid_events[reflect.TypeOf((*BaseEvent)(nil))] = gql_type_base_event | 
			
		
	
		
		
			
				
					
					|  |  |  |   gql_type_base_event.AddFieldConfig("ID", &graphql.Field{ |  |  |  |   gql_type_base_event.AddFieldConfig("ID", &graphql.Field{ | 
			
		
	
		
		
			
				
					
					|  |  |  |     Type: graphql.String, |  |  |  |     Type: graphql.String, | 
			
		
	
		
		
			
				
					
					|  |  |  |     Resolve: func(p graphql.ResolveParams) (interface{}, error) { |  |  |  |     Resolve: GQLEventID, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       if event, ok := p.Source.(Event); ok { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return event.ID(), nil |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       return nil, errors.New("Failed to cast source to event") |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     }, |  |  |  |  | 
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |   }) |  |  |  |   }) | 
			
		
	
		
		
			
				
					
					|  |  |  |   gql_type_base_event.AddFieldConfig("Children", &graphql.Field{ |  |  |  |   gql_type_base_event.AddFieldConfig("Children", &graphql.Field{ | 
			
		
	
		
		
			
				
					
					|  |  |  |     Type: gql_type_event_list, |  |  |  |     Type: GQLListEvent(), | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     Resolve: func(p graphql.ResolveParams) (interface{}, error) { |  |  |  |     Resolve: GQLEventChildren, | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |       if event, ok := p.Source.(Event); ok { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return event.Children(), nil |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |       return nil, errors.New("Failed to cast source to event") |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     }, |  |  |  |  | 
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |   }) |  |  |  |   }) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   gql_type_event_queue := graphql.NewObject(graphql.ObjectConfig{ |  |  |  |   gql_type_event_queue := graphql.NewObject(graphql.ObjectConfig{ | 
			
		
	
		
		
			
				
					
					|  |  |  |     Name: "EventQueue", |  |  |  |     Name: "EventQueue", | 
			
		
	
		
		
			
				
					
					|  |  |  |     Interfaces: []*graphql.Interface{ |  |  |  |     Interfaces: []*graphql.Interface{ | 
			
		
	
		
		
			
				
					
					|  |  |  |       gql_interface_event, |  |  |  |       GQLInterfaceEvent(), | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     }, |  |  |  |     }, | 
			
		
	
		
		
			
				
					
					|  |  |  |     IsTypeOf: func(p graphql.IsTypeOfParams) bool { |  |  |  |     IsTypeOf: func(p graphql.IsTypeOfParams) bool { | 
			
		
	
		
		
			
				
					
					|  |  |  |       _, ok := p.Value.(*EventQueue) |  |  |  |       _, ok := p.Value.(*EventQueue) | 
			
		
	
	
		
		
			
				
					|  |  | @ -437,7 +382,7 @@ func (server * GQLServer) Schema() * graphql.Schema { | 
			
		
	
		
		
			
				
					
					|  |  |  |     Resolve: GQLEventID, |  |  |  |     Resolve: GQLEventID, | 
			
		
	
		
		
			
				
					
					|  |  |  |   }) |  |  |  |   }) | 
			
		
	
		
		
			
				
					
					|  |  |  |   gql_type_event_queue.AddFieldConfig("Children", &graphql.Field{ |  |  |  |   gql_type_event_queue.AddFieldConfig("Children", &graphql.Field{ | 
			
		
	
		
		
			
				
					
					|  |  |  |     Type: gql_type_event_list, |  |  |  |     Type: GQLListEvent(), | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     Resolve: GQLEventChildren, |  |  |  |     Resolve: GQLEventChildren, | 
			
		
	
		
		
			
				
					
					|  |  |  |   }) |  |  |  |   }) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -447,7 +392,7 @@ func (server * GQLServer) Schema() * graphql.Schema { | 
			
		
	
		
		
			
				
					
					|  |  |  |       Name: "Query", |  |  |  |       Name: "Query", | 
			
		
	
		
		
			
				
					
					|  |  |  |       Fields: graphql.Fields{ |  |  |  |       Fields: graphql.Fields{ | 
			
		
	
		
		
			
				
					
					|  |  |  |         "Event": &graphql.Field{ |  |  |  |         "Event": &graphql.Field{ | 
			
		
	
		
		
			
				
					
					|  |  |  |           Type: gql_interface_event, |  |  |  |           Type: GQLInterfaceEvent(), | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |           Resolve: func(p graphql.ResolveParams) (interface{}, error) { |  |  |  |           Resolve: func(p graphql.ResolveParams) (interface{}, error) { | 
			
		
	
		
		
			
				
					
					|  |  |  |             server.lock_holder_lock.Lock() |  |  |  |             server.lock_holder_lock.Lock() | 
			
		
	
		
		
			
				
					
					|  |  |  |             defer server.lock_holder_lock.Unlock() |  |  |  |             defer server.lock_holder_lock.Unlock() | 
			
		
	
	
		
		
			
				
					|  |  | @ -466,21 +411,122 @@ func (server * GQLServer) Schema() * graphql.Schema { | 
			
		
	
		
		
			
				
					
					|  |  |  |     panic(err) |  |  |  |     panic(err) | 
			
		
	
		
		
			
				
					
					|  |  |  |   } |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |   return &schema |  |  |  |   return GQLHandler(schema, context.WithValue(context.Background(), "valid_events", valid_events)) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  | func (server * GQLServer) Init(abort chan error) bool { |  |  |  | func GraphiQLHandler() func(http.ResponseWriter, *http.Request) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |   go func(abort chan error) { |  |  |  |   graphiql_string := ` | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     log.Logf("gql", "GOROUTINE_START for %s", server.ID()) |  |  |  | <!-- | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     h := handler.New(&handler.Config{Schema: server.Schema(), Pretty: true}) |  |  |  |  *  Copyright (c) 2021 GraphQL Contributors | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  *  All rights reserved. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  * | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  *  This source code is licensed under the license found in the | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  *  LICENSE file in the root directory of this source tree. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | --> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | <!DOCTYPE html> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | <html lang="en"> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   <head> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     <title>GraphiQL</title> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     <style> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       body { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         height: 100%; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         margin: 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         width: 100%; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         overflow: hidden; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     mux := http.NewServeMux() |  |  |  |       #graphiql { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     mux.Handle("/gql", h) |  |  |  |         height: 100vh; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     mux.HandleFunc("/", func(w http.ResponseWriter, req *http.Request) { |  |  |  |       } | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     </style> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     <!-- | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       This GraphiQL example depends on Promise and fetch, which are available in | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       modern browsers, but can be "polyfilled" for older browsers. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       GraphiQL itself depends on React DOM. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       If you do not want to rely on a CDN, you can host these files locally or | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       include them directly in your favored resource bundler. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     --> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     <script | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       crossorigin | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       src="https://unpkg.com/react@18/umd/react.development.js" | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     ></script> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     <script | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       crossorigin | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     ></script> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     <!-- | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       These two files can be found in the npm module, however you may wish to | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       copy them directly into your environment, or perhaps include them in your | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       favored resource bundler. | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      --> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     <link rel="stylesheet" href="https://unpkg.com/graphiql/graphiql.min.css" /> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   </head> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   <body> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     <div id="graphiql">Loading...</div> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     <script | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       src="https://unpkg.com/graphiql/graphiql.min.js" | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       type="application/javascript" | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     ></script> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     <script> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       const root = ReactDOM.createRoot(document.getElementById('graphiql')); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       root.render( | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         React.createElement(GraphiQL, { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           fetcher: GraphiQL.createFetcher({ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |             url: 'http://localhost:8080/gql',
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           }), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |           defaultEditorToolsVisibility: true, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |         }), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       ); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     </script> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   </body> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | </html> | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | ` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   return func(w http.ResponseWriter, r * http.Request) { | 
			
		
	
		
		
			
				
					
					|  |  |  |     w.Header().Set("Content-Type", "text/html; charset=utf-8") |  |  |  |     w.Header().Set("Content-Type", "text/html; charset=utf-8") | 
			
		
	
		
		
			
				
					
					|  |  |  |     w.WriteHeader(http.StatusOK) |  |  |  |     w.WriteHeader(http.StatusOK) | 
			
		
	
		
		
			
				
					
					|  |  |  |     io.WriteString(w, graphiql_string) |  |  |  |     io.WriteString(w, graphiql_string) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | type GQLQuery struct { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   Query string `json:"query"` | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | func GQLHandler(schema graphql.Schema, ctx context.Context) func(http.ResponseWriter, *http.Request) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   return func(w http.ResponseWriter, r * http.Request) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     str, err := io.ReadAll(r.Body) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if err != nil { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       log.Logf("gql", "failed to read request body: %s", err) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       return | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     res := GQLQuery{} | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     log.Logf("gql", "GQL_REQ: %s", str) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     json.Unmarshal(str, &res) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     log.Logf("gql", "GQL_QUERY: %s", res.Query) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     result := graphql.Do(graphql.Params{ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       Schema: schema, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       Context: ctx, | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       RequestString: res.Query, | 
			
		
	
		
		
			
				
					
					|  |  |  |     }) |  |  |  |     }) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     if len(result.Errors) > 0 { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |       log.Logf("gql", "wrong result, unexpected errors: %v", result.Errors) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     json.NewEncoder(w).Encode(result) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | func (server * GQLServer) Init(abort chan error) bool { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |   go func(abort chan error) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     log.Logf("gql", "GOROUTINE_START for %s", server.ID()) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     mux := http.NewServeMux() | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     mux.HandleFunc("/gql", server.Handler()) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     mux.HandleFunc("/", GraphiQLHandler()) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     srv := &http.Server{ |  |  |  |     srv := &http.Server{ | 
			
		
	
		
		
			
				
					
					|  |  |  |       Addr: server.listen, |  |  |  |       Addr: server.listen, | 
			
		
	
	
		
		
			
				
					|  |  | 
 |