Tile Caching Using IndexedDB

WIP
Cache Tiles using IndexedDB. Create a new Tile Request Channel which connects to an IDBDatabase. Through the channel, search for tiles in the db. If a match is found, check if the tile has expired (based on time of storage). If expired, delete the tile from the db and move to the next request channel. If no match is found, move to the next request channel. Once a tile has been successfully requested, store it in the db.

Things still needing to be confirmed/investigated further:
Opening/Closing the DB - when/where should the db be opened? As of now, it's opened as a part of the constructor for the local storage request channel. Should that be changed to part of the IModelTileMetadataCacheChannel, or put somewhere else entirely? When should we close/clear the db? Maybe based on a total size of the stored content? As of now, there is no logic implemented for closing or clearing.
Testing the content storage and return - is the tile content actually being successfully stored in and returned from the db, saving from regenerating the tile? Is there a better way to obtain a successfully requested tile for storage besides using the rpc channel's content callback to store the tile in the db?
Built-in browser caching - Is the browser caching any of these tiles already, meaning we are doing unnecessary work by adding them to a second cache? Should we somehow check to see what the browser has cached and avoid caching those tiles in the db?
TileAdmin toggle flag - Eventually, we will most likely want this functionality to be on by default. But for now, should there be a flag similar to TileAdmin.Props.cacheTileMetadata to toggle this functionality?

When I asked, you told me you are caching all kinds of tiles, but this only caches iModel tiles. Did you change your mind?

When I asked, you told me you are caching all kinds of tiles, but this only caches iModel tiles. Did you change your mind?

My original thought was that all types of tiles were going through these channels, but seeing as these are IModelTileRequestChannels, that seems sort of obviously wrong in retrospect... My bad. I believe the final goal is to cache all types of tiles, so that is something still to do.

As a first step, caching iModel tiles is enough, and we can focus on the rest of tile types later.

How do you plan to measure the effectiveness of these changes?

For now, I'd just check if tiles are being correctly stored, even with SaS tokens. That can be checked manually in the debug console.
The end game is to use this with "incremental tiles", in which we re-use old tiles. There is where the big wins will come. Until then, this is more to test the viability of the approach than for having quick performance wins (if local cache doesn't work, incremental tiles don't make that much sense)

Sure, I just don't want us to enable it for users until it's providing actual value.

The tile request channels you are modifying are used for tiles that are produced on demand by the imodel backend.
Tiles produced by mesh export service go through a different channel.

Thanks for mentioning it!
I didn't expect us to activate this now either.
Does it make sense to integrate this functionality behind an option disabled by default?

 Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you all sign our Contributor License Agreement before we can accept your contribution.1 out of 2 committers have signed the CLA.:white_check_mark: andremig-bentley:x: AndreMigYou have signed the CLA already but the status is still pending? Let us recheck it.


SOLR-16470 : Create V2 equivalent of V1 Replication: GET files

https://issues.apache.org/jira/browse/SOLR-16470

Description
Create a V2 equivalent API for the replication "GET filelist"
V1
/solr/{coreName}/replication?command=filelist&generation={genNumber}
V2
/api/cores/{coreName}/replication/files?generation={genNumber}
Solution
Created a new endpoint in CoreReplicationAPI class using JAS-RX framework. I then moved the logic of the filelist from the ReplicationHandler class into the CoreReplicationAPI class and updated the V1 endpoint to use the CoreReplicationAPI class so that the ReplicationHandler can be deprecated in the future.
Tests
Wrote new Unit test in CoreReplicationAPITest that will mock a response from getFileList into a NamedList object.
Checklist
Please review the following and check all that apply:

[x] I have reviewed the guidelines for How to Contribute and my code conforms to the standards described there to the best of my ability.
[x] I have created a Jira issue and added the issue ID to my pull request title.
[x] I have given Solr maintainers access to contribute to my PR branch. (optional but recommended)
[x] I have developed this patch against the main branch.
[x] I have run ./gradlew check.
[x] I have added tests for my changes.
[x] I have added documentation for the Reference Guide

@gerlowskija Could you take a look at this PR when you get a chance?

Merged - will target backporting next week if test runs over the weekend don't surface any issues.  Thanks again @mlbiscoc!

@gerlowskija, this broke precommit (for jenkins and github actions) https://github.com/apache/solr/actions/runs/5425690231/jobs/9866774872

@gerlowskija, this broke precommit (for jenkins and github actions) https://github.com/apache/solr/actions/runs/5425690231/jobs/9866774872

Sorry about that. ./gradlew check passed running locally on my laptop. Did I miss a step and if so, what can I do to avoid this in the future?

No worries, its annoying because that gradle validation only runs if it can tell its running in a Github Action or in Jenkins. So you can't tell locally.
If you look at the checks for the last commits in this PR, you can see that the precommit check failed. That's the only real way to catch it before committing.

@gerlowskija, this broke precommit (for jenkins and github actions) https://github.com/apache/solr/actions/runs/5425690231/jobs/9866774872

Sorry about that. ./gradlew check passed running locally on my laptop. Did I miss a step and if so, what can I do to avoid this in the future?

if fails for me locally with -Pvalidation.errorprone=true
fyi https://github.com/apache/solr/pull/1751


composer: let expiry be passed through APIs

The Koji API always sets the expiry to 1 day, for the Weldr and Cloud APIs the value can be provided in the request. If the value is not passed then the default is used: 14 days.
I'm not entirely too sure on using '0' as the placeholder for 'no expiry', I don't like in-value things like this but I'm unsure if it'd be sane to pass around *int64.
This PR still needs tests and (likely) some documentation but I'd like people to tell me if I'm doing crazy stuff as this is my-first-Go.
This pull request includes:

[ ] adequate testing for the new functionality or fixed issue
[ ] adequate documentation informing people about the change such as

[ ] submit a PR for the guides repository if this PR changed any behavior described there: https://www.osbuild.org/guides/

What's the behavior of the weldr api if the backing job is gone? Is this a behavioral change? If so: do we want it? Is it necessary?
I wonder if the default for weldr should be to not expire, but I could be wrong?
cc @ondrejbudai @bcl

What's the behavior of the weldr api if the backing job is gone? Is this a behavioral change? If so: do we want it? Is it necessary?

I would prefer no expiration for weldr jobs, seems too smart for a local service (imagine buildah expiring images after 14 days).


Lua Syntax highlighting is a bit off

In reference to the following:

https://github.com/atom/atom/issues/307#issuecomment-83321700
https://github.com/atom/atom/issues/307#issuecomment-84233748

This package does not take into account typos or core Lua functions. It would be nice if it did so.

I would like to also note here that the syntax highlighting for a function that belongs to a table with numbers in the name is also off.
local function i18n.new() end

Using the monokai theme, this comes up as blue (as if I were calling the function) instead of green (as if I were defining the function)
However, this seems to highlight (green) correctly:
local function i18n() end


Add Tucson Hybrid 2021 carFw

c3231807b9f5b5f6

Thanks for the PR. This should be opened against master at commaai:openpilot. If you can provide the dongle ID, I can help with making a PR for this.


Add a new oldest_xmin check.

This implements the check mentioned in https://github.com/OPMDG/check_pgactivity/issues/201.
I'm not extremely sure of the pg_stat_activity part.  The problems I can see are:

as soon as eg. a transaction retains some xid, active queries started after will also look like they're retaining the same amount of transactions.  However, if t hose queries continue to run after the initial transaction is finished, they'll be the source of retention.  So it's quite hard to really identify what actually retains the xmin horizons from an aggregated view.  The query is already complex enough, so I'm not in favor of adding extra steps to try to be smarter about that.

For pg_stat_activity, I'm not exactly sure if both backend_xmin and backend_xid can both be earlier than the other.  Minimal testing showed than coalesce(backend_xmin, backend_xid) was enough, but I certainly didn't try a lot of scenario.

As discussed off thread, I realized that I forgot to also handle the impacted databases.  I just pushed an additional commit (that should be squashed, after a rebase I'll take care of that once everything is ok) to fix both that and @ioguix comments.

Hey @rjuju,
I've been reviewing and testing. I closed all our active conversations as we finished discussing all of them.
I fixed a bug in the query were some NaN perfdata (idle_xact or active_xact or query) were not shown for database when they were set in other databases.
Please, do some test/review and fixup/merge when you are ok.

BTW, with only 4 connectable db (including template1 and postgres), I gathered 48 perfdatas. 12 metrics per database.
Maybe we can add a --summary arg or equivalent to only provide in perfdata the oldest xmin/age per database, and report in long messages what is the oldest horizon for each database?

+1 for a --summary option.

Thanks @ioguix
I'm fine with a --summary option.  However, just to be clear I don't expect anyone using that check for all databases nor for a long time.  It's really a diagnosis check to help track down bloat issue happening at some random interval, but the rest of the time you don't really need to monitor it.
I'll review the changes soon.

As discussed on IRC, I added a few commits:

thresholds are now optionnal
the check is now terse by default: one perfdata (oldest age) per database plus one info per database (what is the kind of the oldest xmin) in messages if there's some data to show.
new arg --detailed throw detailed perfdatas (12) for each database

Please, review.
++

I'm fine with the new behavior.  About the patch, I think we should document the new --detailed option along with the other ones.
I also see that you don't check for compatibility with this option.  Is that intended?  I'm not sure if anyone will blindly add a --detailed everywhere just in case so that's may not be a huge problem, but until now our current approach is to explicitly check for every single option compatibility.

About the patch, I think we should document the new --detailed option along with the other ones.

Well, a lots of specifics argument are not documented with other, normal, ones. Specifics ones are only documented in their related service. Eg.: --query, --path, --type, --suffix, --uid, GUCs, --unarchiver, etc.

I also see that you don't check for compatibility with this option. Is that intended?

Fixed in last commit.


Zerocopy unsound on SPIR-V target?

From a comment in the implementation of mem::swap:
// NOTE(eddyb) SPIR-V's Logical addressing model doesn't allow for arbitrary
// reinterpretation of values as (chunkable) byte arrays, and the loop in the
// block optimization in `swap_slice` is hard to rewrite back
// into the (unoptimized) direct swapping implementation, so we disable it.
// FIXME(eddyb) the block optimization also prevents MIR optimizations from
// understanding `mem::replace`, `Option::take`, etc. - a better overall
// solution might be to make `ptr::swap_nonoverlapping` into an intrinsic, which
// a backend can choose to implement using the block optimization, or not.

It's not immediately clear to me whether this is a problem for us, but it's also not immediately clear that it's not. Thankfully, SPIR-V is unlikely to represent significant use among our users, so it's not a critical issue. Of course, we still can't compile code we're not 100% sure is sound, so we'll need to disable that target for the time being until we can investigate further.
Tasks:

[ ] Fail compilation when compiling for SPIR-V, emitting a brief warning and a link to this issue, e.g.: #[cfg(target_arch = "spirv")]
 compile_error!("Zerocopy has a suspected soundness hole on SPIR-V; if this affects you, please let us know at https://github.com/google/zerocopy/issues/383");

[ ] Look into this in more detail

Given zerocopy's ethos of always, definitely being sound, we should perhaps take the even more conservative route of producing a compile_error on all architectures except the ones we know are sound. That way, we won't have a repeat of this issue if rustc later adds support for another unsupportable architecture.

Hmm very good point. Want to edit the text/title of this issue to track that broader task? I'm thinking we could change the error message to something that conveys:

Zerocopy hasn't been proven sound on this target architecture
That isn't cause for alarm - it just means we haven't gotten around to doing it
Comment on this issue if you need support a not-yet-supported target

It'd also be good to track potential support by target so we have a place to write the note about SPIR-V so we don't forget and spuriously re-enable support.
Looks like compile_error supports multi-line string literals, but the output is a bit weird - only the first line is colored red, and the rest are black.

Closed in https://github.com/google/zerocopy/pull/485


Generics extending unions cannot be narrowed

TypeScript Version:  2.2.0-dev.20170126
Code
declare function takeA(val: 'A'): void;
export function bounceAndTakeIfA<AB extends 'A' | 'B'>(value: AB): AB {
    if (value === 'A') {
        takeA(value);
        return value;
    }
    else {
        return value;
    }
}

Expected behavior:
Compiles without error.
Actual behavior:

Argument of type 'AB' is not assignable to parameter of type '"A"'.

It works correctly if I just use value: 'A' | 'B' as the argument to bounceAndTakeIfA, but since I want the return value to type-match the input, I need to use the generic (overloading could do it, but overloading is brittle and error-prone, since there is no error-checking that the overload signatures are actually correct; my team has banned them for that reason). But (I'm guessing) since AB extends 'A' | 'B', narrowing doesn't happen. In reality, I am just using extends to mean AB ⊂ 'A' | 'B', but extends can mean more than that, which (I suspect) is why TS is refusing to narrow on it.
Some alternative to extends that more specifically means ⊂ (subsets maybe?) would probably be the best solution here?

But extends already does mean subset. If I'm not mistaken, extends is simply TypeScript's implementation of bounded quantification. Do you have a specific example of behavior where you'd do T extends U for some T not assignable to U?

TL;DR from design discussion: It's somewhat obvious what the "right" thing to do is, but would require a large rework of how we treat type parameters, with concordant negative perf impacts, without a corresponding large positive impact on the actual user-facing behavior side.
If new patterns emerge that make this more frequently problematic, we can take another look.

Again appeared in #25039

How should I write such code then?
type NumberType = (() => number) | number;

function double<T extends NumberType>(
    num: T
) : T {
    if (typeof num === "number") return num * 2;
    return () => num() * 2;
}```

Error `Type 'number' is not assignable to type 'T'.`

By using return num * 2 as T; and return () => num() * 2 as T;, unfortunately. There is no better way, because while TS will narrow num it will never narrow T for you.

same issue, different example:
interface AllowedMapTypings {
    'str': string;
    'lon': number;
}

const obj: AllowedMapTypings = {
    'str': 'foo',
    'lon': 123
};

function foo<T extends keyof AllowedMapTypings>(key: T): AllowedMapTypings[T] {
    return obj[key];
}
let str = foo('str'); // this works fine, str is a string

function fn<T extends keyof AllowedMapTypings>(key: string, kind: T, value: AllowedMapTypings[T]) {
    if (kind === 'str') {
        console.log(value.length); // Property 'length' does not exist on type 'AllowedMapTypings[T]'.
    }
}

This would be great for specializing Props to React components. Contrived example:
type Type = 'a' | 'b';
type AShape = { a: 'a' };
type BShape = { b: 'b' };
type Props<T extends Type> = {
  type: T,
  shape: T extends 'a' ? AShape : BShape,
};

class Test<T extends ID> extends React.Component<Props<T>> {
  render() {
    const { type, shape } = this.props;
    switch (type) {
      case 'a':
        return <>{shape.a}</>;
      default:
        return <>{shape.b}</>;
    }
  }
}

Here is an example that demonstrates the difference in behaviour between non-generic and generic functions:
type Common = { id: number };
type A = { tag: 'A' } & Common;
type B = { tag: 'B' } & Common & { foo: number };

type MyUnion = A | B;

const fn = (value: MyUnion) => {
    value.foo; // error, good!
    if ('foo' in value) {
        value.foo; // no error, good!
    }
    if (value.tag === 'B') {
        value.foo; // no error, good!
    }
};

const fn2 = <T extends MyUnion>(value: T) => {
    value.foo; // error, good!
    if ('foo' in value) {
        value.foo; // error, bad!
    }
    if (value.tag === 'B') {
        value.foo; // error, bad!
    }
};

I think this is the same issue, this came from a real use case but I've reduced it to a toy example to better demonstrate:
interface Foo {
  stringVal: string;
  stringArrayVal: string[];
  numberArrayVal: number[];
}

type KeysWithType<T, V> = { [K in keyof T]: T[K] extends V ? K : never }[keyof T];

type ArrayPropertyOf<T> = KeysWithType<T, Array<any>>;

type ArrayTypeOfPropertyOf<T, K extends keyof T> = T[K] extends Array<infer U> ? U : never;

/// type checks

const obj: Foo = {
  stringVal: 'hello',
  stringArrayVal: ['world'],
  numberArrayVal: [1,2,3]
}

let a: ArrayTypeOfPropertyOf<Foo, 'numberArrayVal'>; // as expected, type narrowed to number.

function printArrayKeyWorking(key: ArrayPropertyOf<Foo>) {

  switch (key) {
    case 'stringArrayVal':
    case 'numberArrayVal':
    case 'stringVal': // as expected: Type '"stringVal"' is not comparable to type '"numberArrayVal" | "stringArrayVal"'.
      console.log(key);
  }

}

function printArrayKeyNotWorking<K extends ArrayPropertyOf<Foo>>(key: K) {

  switch (key) {
    case 'stringArrayVal':
    case 'numberArrayVal':
    case 'stringVal': // no error
      console.log(key);
  }

}

function transformChildArrayValue<K extends ArrayPropertyOf<Foo>>(key: K, value: ArrayTypeOfPropertyOf<Foo, K>) {

  switch (key) {
    case 'stringArrayVal':
      return value.repeat(2); // not expected: Type '"stringVal"' is not comparable to type '"numberArrayVal" | "stringArrayVal"'.
    case 'numberArrayVal':
      return value ** 2; // not expected: The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.
    case 'stringVal':
      return key;
  }

}

Is there actually a workaround existing for this? The real case I'm having is the same kind of problem as the last function where I am unable to correctly type the key name and value as the two parameters as the type cannot be correctly narrowed. Note this is part of a library that I want to enforce good types for the downstream developer so I'm looking for generic solution not one specific to this particular problem
Any tips for a workaround greatly appreciated!

Not sure if that's the exact same problem, but I probably found a real simple case where this doesn't work as expected:
function ifNullThenUndefined<T>(value: T): T extends null ? undefined : T {
    return value === null ? undefined : value;
}

This complains at the return statement that Type 'undefined' is not assignable to type 'T extends null ? undefined : T'. See playground.
This, however, works:
type MapNullToUndefined<T> = T extends null ? undefined : T;

export function ifNullThenUndefined<T>(value: T): MapNullToUndefined<T> {
    return (value === null ? undefined : value) as MapNullToUndefined<T>;
}

const a1 = ifNullThenUndefined(null); // a1 is inferred as undefined
const a2 = ifNullThenUndefined(undefined); // a2 is inferred as undefined
const a3 = ifNullThenUndefined(2); // a3 is inferred as a number

See playground.

@jhnns This is actually more closely related to another issue I’d raised, #21879. Basically, Typescript never considers the narrowing of a value, e.g. value as inplying anything about the type, e.g. T, that value has. The reason why is this:
interface A { foo: 42; }
interface B { bar: 'hello world'; }
declare function isB(value: A | B): value is B;

type Foobar<T extends A | B> = T extends A ? 'foo' : 'bar';

function demo<T extends A | B>(value: T): Foobar<T> {
    if (isB(value)) {
        return 'bar';
    }
    else {
        return 'foo';
    }
}

// here is the problem:
demo({ foo: 42, bar: 'hello world' });

In that function call, T is A & B, which means it will pass isB and return 'bar'. But the definition of Foobar says that Foobar<A & B> should be 'foo' instead.
The “solution,” such as it is, is to use casting. Whether you do that by defining a particular type (e.g. MapNullUndefined or by just writing out as T extends null ? undefined : T, either works, but you basically are forced to tell the compiler that you have done this right, which means the compiler cannot correct you if you have not, in fact, done it right.
Which drastically limits the value of conditional types, in my opinion, since they will almost-always, necessarily, be unsafe at least within the internals of the function. And plenty of cases where A & B is never exist, which could be handled safely, but the TS team seems to be uninterested in going down that road.

Trying to work around the fact that generic types extending union types don't get narrowed, I came up with the following example:
type Union = "A" | "B";

function differentiate(value: "A"): Array<"A">;
function differentiate(value: "B"): Array<"B">;
function differentiate(
  value: Union
): Array<"A"> | Array<"B"> {
  switch (value) {
    case "A":
      return [value];
    case "B":
      return [value];
  }
}

const arrayA = differentiate("A"); // resulting type is Array<"A"> ✅
const arrayB = differentiate("B"); // resulting type is Array<"B"> ✅

function calling(u: Union) {
  differentiate(u); // ⛔ Argument of type 'Union' is not assignable to parameter of type '"B"'.
  return u === "A" ? differentiate(u) : differentiate(u); // Works but problematic when Union includes more litterals
}

I would have expected this code to work:
type Union = "A" | "B";

function differentiate<T extends Union>(
  value: T
): Array<T> {
  switch (value) {
    case "A":
      return [value]; // value should be of type "A"
    case "B":
      return [value]; // value should be of type "B"
  }
}

const arrayA = differentiate("A"); // resulting type should be Array<"A">
const arrayB = differentiate("B"); // resulting type is Array<"B">

function calling(u: Union) {
  return differentiate(u);
}

Thank you in advance for any input you may have!

I think this is related:
type Payload = {
    data: {
        id: string;
        hi: {
            id: string;
        };
    }
}

type Filter<T extends Payload> = {
    [K in keyof T]: T[K] extends { id: any } | undefined | null ? K : never;
};
type HasId<T extends Payload> = Filter<T>[keyof T];

const genericVersion = <T extends Payload> (something: T): HasId<T> => {
    return 'data'; // Errors
}

const staticVersion = (): HasId<Payload> => {
    return 'data'; // Success
}

const main = () => {
    let d = genericVersion({ data: { id: '', hi: { id: '' } } });
}

Basically, it works if there's a concrete type, but ignores the extends type bound when used as a generic.

This issue is framed as being about unions, but is the underlying cause related to unions at all? E.g., this fails as well, and no unions (or generic constraints) are involved, but I think the same thing's going on:
export default function transformOrReturn<T>(v: T): T {
  if (typeof v === 'string') {
    // ERROR: Type 'string' is not assignable to type 'T'.
    return transformString(v)
  }

  return v;
}

declare function transformString(it: string): string;

Clearly, the call in the if block should not be an error, but it is — even though the type of v in that branch is narrowed to T & string. TS isn't realizing that, for that block  to be entered at all, it must be that T extends string

Ran into this in my production code as well. SO post: https://stackoverflow.com/questions/58347967/how-can-i-make-this-generic-typescript-function-work-as-expected

I'm running into this issue a lot, and would love to see it fixed.  In particular, I'd love for the type system to be able to track a value of type T both for its relationship with T and its possible (narrowed) type.
My dream would be if both of these errors could go away:
declare function takeA(val: 'A'): void;

export function bounceAndTakeIfA<T extends 'A' | 'B'>(value: T): T {
    if (value === 'A') {
        takeA(value); // error 1
        return value;
    }
    else {
        return 'B'; // error 2
    }
}

const x = bounceAndTakeIfA('A')

A workaround worth noting is using a single overload with the generic type signature, before writing the function without the type parameter:
declare function takeA(val: 'A'): void;

export function bounceAndTakeIfA<T extends 'A' | 'B'>(value: T): T
export function bounceAndTakeIfA(value: 'A' | 'B'): 'A' | 'B' {
    if (value === 'A') {
        takeA(value); // error 1
        return value;
    }
    else {
        return 'B'; // error 2
    }
}

const x = bounceAndTakeIfA('A')

The flaw with this approach, of course, is that the body of the function is not checked to ensure the relationship specified by the type parameter T.  It's also verbose.  However, if you are doing casting at each site, you are also losing these guarantees, and being verbose.

I want to implement a function which gets an ID (which can be a string or a number) or an array of IDs and coerces it into a number or an array of numbers. Basically it needs to implement the following overloads:
export function ensureIsNumber(id: string | number): number;
export function ensureIsNumber(ids: string[] | number[]): number[];

I thought of somethig like that:
function ensureIsNumber<T extends string | number, K extends T | Array<T>>(
  idOrIds: K
): K extends Array<T> ? number[] : number {
  if (idOrIds instanceof Array) {
    return idOrIds.map(id => Number(id));
  } else {
    return Number(idOrIds);
  }
}

UnfortunatelyTypescript cannot narrow it down :(
Is there any other way to implement it?

Add an explicit cast. Any other way you try will still be unsound, whether TS complains or not.

@AnyhowStep

Add an explicit cast. Any other way you try will still be unsound, whether TS complains or not.

Assuming (number|string) & (number|string)[] is impossible, which I think is a safe assumption, idOrIds instanceof Array does soundly imply that K is an array type, which would soundly imply that the return type should be number[]. The actual signature of the function, as written, might be flawed, but it should be possible to soundly deduce this without need for casting. And there are many similar cases.
Basically what it often comes down to is mutually-exclusive unions can (and, per this suggestion, should) be narrowed, but because of the problems when unions are not mutually exclusive, TS doesn’t. I strongly hope that someday TS will be smarter about recognizing and leveraging mutually-exclusive unions.

It's "unsound" as in, the other way to implement it would be with overloads but TS doesn't protect you from making mistakes there, either,
export function ensureIsNumber(id: string | number): number;
export function ensureIsNumber(ids: string[] | number[]): number[];
export function ensureIsNumber(idOrIds: string|number|(string|number)[]): number|number[] {
  if (idOrIds instanceof Array) {
    return 999; //not an array
  } else {
    return [111]; //not a number
  }
}

A "sound" approach would be some variant of the above that would protect you from making that mistake. As of now, no such approach exists. So, any approach is fine because they're all not great.
(The best would be to not use overloads in the first place)

@AnyhowStep
That's basically what I ended up implementing, but I preferred to avoid using overloads because of the issue you mentioned.
Just a couple of notes:
(string|number)[] is different than string[] | number[] because it will allow mixed types like [1, 'abc'].
Also:
function ensureIsNum(
  idOrIds: string | number | string[] | number[]
): number | number[] {
  if (idOrIds instanceof Array) {
    return idOrIds.map(id => Number(id));
  } else {
    return Number(idOrIds);
  }
}

In the previous example you won't be able to access the map method unless you cast idOrIds to Array<any>: somehow string[] | number[] is not an array for Typescript.

(string|number)[] is different than string[] | number[] because it will allow mixed types like [1, 'abc'].

Yes, but no one will see (string|number)[] from the outside as it is the implementing signature.
And I used (string|number)[] to avoid that problem you're having with ((string[])|(number[])).map()

can I throw my example (from my https://github.com/microsoft/TypeScript/issues/36521#issuecomment-592931518)
in the mix asking how to solve it I hope it will b a constructive question in regard to the problem
How can I test in order to split my code into two possibilities (like my if check on null in my code example at the bottom if (this.value !== null))
  // I wan to branch to those 2 possibilities:
   ((value: T, index: number, array: T[]) => R
   | (value: Promise<T>, index: number, array: Promise<T>[]) => Promise<R>)

To avoid:
Argument of type 'T[] | Promise<T>[]' is not assignable to parameter of type 'T[]'.
  Type 'Promise<T>[]' is not assignable to type 'T[]'.
    Type 'Promise<T>' is not assignable to type 'T'.

Maybe my code is just wrong and I don't know
My code:
  public listMap<R>(
fn: (
      value: T | Promise<T>,
      index: number,
      array: T[] | Promise<T>[]
    ) => R | Promise<R>,
    thisArg?: any
  ) {
    if (this.value !== null) {
       return new MaybeList<R>(this.value.map<R>(fn, thisArg))
    }
    return new MaybeList<null>();
  }

this.value is defined by  private value!: T[] | Promise<T>[] | null;
error message: (this.value.map())
  This expression is not callable. Each member of the union type
  '(<U>(callbackfn: (value: T, index: number, array: T[]) =>
  U, thisArg?: any) => U[]) |
  (<U>(callbackfn: (value: Promise<T>, index: number, array: Promise<T>[]) =>
  U, thisArg?: any) => U[])'
  has signatures, but none of those signatures are compatible with each other.
  ts(2349)

A Playground would make things easier to work with.

Even though it does not use generics, the following example seems to be in the same family of problems since it resembles #31743 which was closed as duplicate of this issue:
class Test {
    a: string;
    b: string;
    c: number;

    constructor() {
        this.a = "a";
        this.b = "b";
        this.c = 1;
    }

    test(key: keyof this): number {
        switch (key) {
            case "a":
            case "b":
            return this[key].length; // Property 'length' does not exist on type 'this[keyof this]'.(2339)
            case "c":
            return this[key]; // Type 'this[keyof this]' is not assignable to type 'number'.(2322)
        }
        return 0;
    }
}

Also this issue comes up when you want to write mapper for some AST-like type:
enum TYPE {
  BOOLEAN = 'BOOLEAN',
  STRING = 'STRING',
  FLOAT = 'FLOAT',
  COMPLEX = 'COMPLEX',
}

type BooleanValue = {
  type: TYPE.BOOLEAN;
  value: boolean;
};

type StringValue = {
  type: TYPE.STRING;
  value: string;
};

type FloatValue = {
  type: TYPE.FLOAT;
  value: number;
};

type PrimitiveValue = BooleanValue | StringValue | FloatValue;

type ComplexValue = {
  type: TYPE.COMPLEX;
  value: PrimitiveValue;
};

type Value = PrimitiveValue | ComplexValue;

function mapValueGeneric<T extends Value>(value: T, f: (_: PrimitiveValue) => PrimitiveValue): T {
  switch (value.type) {
    case TYPE.BOOLEAN:
    case TYPE.STRING:
    case TYPE.FLOAT:
      return f(value); // error 2322: Type 'PrimitiveValue' is not assignable to type 'T'.
                       // error 2345: Argument of type 'T' is not assignable to parameter of type 'PrimitiveValue'.
    case TYPE.COMPLEX:
      return {
        type: TYPE.COMPLEX,
        value: mapValueGeneric(value.value, f), //error 2322: Type '{ type: TYPE.COMPLEX; value: Value; }' is not assignable to type 'T'.
      };
  }
}

function mapValueSimple(value: Value, f: (_: PrimitiveValue) => PrimitiveValue): Value {
  switch (value.type) {
    case TYPE.BOOLEAN:
    case TYPE.STRING:
    case TYPE.FLOAT:
      return f(value);
    case TYPE.COMPLEX:
      return {
        type: TYPE.COMPLEX,
        value: mapValueSimple(value.value, f),// error 2322: Type 'Value' is not assignable to type 'string | number | boolean | BooleanValue | StringValue | FloatValue'.
      };
  }
}

Playround

Just a minimal example that shows perfectly the issue and why it should be solved in a way or another:
type A = {
    testable: true
    doTest: () => void
}
type B = {
    testable: false
};

type Union = A | B

function notWorking<T extends Union,>(object: T) {
    if (!object.testable) return
    object.doTest() // Property 'doTest' does not exist on type 'T'. Did you mean 'test'?
}

Please, note that the following function would work:
function working(object: Union) {
    if (!object.testable) return
    object.doTest()
}

@Sharcoux, why you need generic type in this case, why not just accept erased type? For me it is not the best illustration of issue. This issue comes up when you want to preserve input type, so need to use it as return type (like in my example above), or if you want to have two or more function parameters of exactly same type.

What do you call erased type?

@Sharcoux, when you use interface as type, not as generic's restriction (so lose information about what original type was)

@RyanCavanaugh
hi, do you have any updates about this topic?
Maybe something has changed in the two years since you wrote!

but would require a large rework of how we treat type parameters, with concordant negative perf impacts, without a corresponding large positive impact on the actual user-facing behavior side.

It would be good if you could just give us a short information. Thank you very much.

It's somewhat obvious what the "right" thing to do is, but would require a large rework of how we treat type parameters, with concordant negative perf impacts (...)

@RyanCavanaugh I feel like prioritizing speed over a sound type-system is kind of a contradiction here.  We use TypeScript to have a type-system.  If there are large gaps in it's type-system, and I do consider this a large gap, TypeScript should correct them.  Every omission like this hurts its usefulness as a tool we can rely on.  It is its one, singular job to reason about types correctly.
That said: two years ago, it might've been true that this was not a common pattern.  But two years later, these patterns are now everywhere.  There's even examples of these kinds of generics in TypeScript's standard definitions and utility types.
The thing is, definitions don't necessarily check against an implementation.  You can just say something takes a type-parameter with a union type constraint, and this issue is essentially swept under the rug from a user-facing perspective.  The external API-level side all type-checks fine.
But the pattern can't be repeated in a real function implementation and have those types do their intended work.  We should not need to slap // @ts-ignore - TS being dumb again to force it to swallow its own valid types.
It's really time to fix this one.  At least TS has incremental compilation now, so hopefully speed isn't an issue now either.

@RyanCavanaugh is there any plan to fix that? I encounter it a lot and it would be great if you could address that.

@RyanCavanaugh please consider fixing this again

Just leave  this SO question here

Seems like it also affects generics extending enums.
I am trying to make a factory class that accepts enums as inputs and instantiates the appropriate class based on the enum provided.
class ReportA {
   constructor(public type: ReportType.A) { }
}

class ReportB {
   constructor(public type: ReportType.B) { }
}

enum ReportType {
   A = "A",
   B = "B"
}

/** Example 1 using generics. Does not work. */
class ReportFactory<Type extends ReportType> {
   constructor(public type: Type) { }

   public create = () => {
      switch (this.type) {
         case ReportType.A: {
            /** ERROR! */
            return new ReportA(this.type)
         }
         case ReportType.B: {
            /** ERROR! */
            return new ReportB(this.type)
         }
         default: throw new Error()
      }
   }
}

/** Example 2 without generics. Works */
class ReportFactory2 {
   constructor(public type: ReportType) { }

   public create = () => {
      switch (this.type) {
         case ReportType.A: {
            /** WORKS! */
            return new ReportA(this.type)
         }
         case ReportType.B: {
            /** WORKS! */
            return new ReportB(this.type)
         }
         default: throw new Error()
      }
   }
}

Playground

Could we get better compiler feedback for this issue? What I got did not lead me to think that it was a limitation.

Quoting the previous comment

Could we get better compiler feedback for this issue? What I got did not lead me to think that it was a limitation.

In case doing the "right" thing proves to be too complex and will take (and most likely it will) a lot of time (or won't be implemented at all) I'd be grateful (and probably many other) for considering the above suggestion.
I've spent most of my day today trying to figure out what mistake I have made in my types, then a couple of hours searching through the internet and in the end stumbled upon this thread to find out it wasn't me 😅

Quoting the previous comment

Could we get better compiler feedback for this issue? What I got did not lead me to think that it was a limitation.

In case doing the "right" thing proves to be too complex and will take (and most likely it will) a lot of time (or won't be implemented at all) I'd be grateful (and probably many other) for considering the above suggestion.
I've spent most of my day today trying to figure out what mistake I have made in my types, then a couple of hours searching through the internet and in the end stumbled upon this thread to find out it wasn't me 😅

@RyanCavanaugh, I have a more hypothetical question 🙂 Are you open to receiving suggestions for this issue? In principle, I would be interested in looking into this, but I have a few questions.

From your previous comment,

would require a large rework of how we treat type parameters

I gather that you think fixing this would be a large undertaking, but how big of an undertaking you think it would be? From everything, you can see, do you think it would be feasible to come up with a first draft within a month?

Are there any higher-level concepts that would have to be affected by a fix?

Of course, better type inference here would certainly incur some kind of performance cost, but are there any performance-pitfalls you can already see us running into with a fix?

Thank you in advance for spending time on those questions!

@RyanCavanaugh, I have a more hypothetical question 🙂 Are you open to receiving suggestions for this issue? In principle, I would be interested in looking into this, but I have a few questions.

From your previous comment,

would require a large rework of how we treat type parameters

I gather that you think fixing this would be a large undertaking, but how big of an undertaking you think it would be? From everything, you can see, do you think it would be feasible to come up with a first draft within a month?

Are there any higher-level concepts that would have to be affected by a fix?

Of course, better type inference here would certainly incur some kind of performance cost, but are there any performance-pitfalls you can already see us running into with a fix?

Thank you in advance for spending time on those questions!

Hello!
I think I fell on this same issue. Here's my example:
function test1<T, K1 extends keyof T | ((a: T) => R), R>(t: T, a: K1) {
  // Compiling Error. It Can't understand a is callable in the first, and a key of T in the second
  return typeof a === 'function' ? a(t) : t[a];
}
function test2<T, R>(t: T, a: keyof T | ((a: T) => R)) {
  // Works as intended
  return typeof a === 'function' ? a(t) : t[a];
}

Playground Link
Still related to this issue, I have an extended example of the above one where I also had a compiler error:
function test1<T, K1 extends keyof T | ((a: T) => R), R>(t: T, a: K1) {
    return typeof a === 'function' ? a(t) : t[a];
}
function test2<T, R>(t: T, a: keyof T | ((a: T) => R)) {
  return typeof a === 'function' ? a(t) : t[a];
}

function max<T, R>(mapper: (a: T) => R) {
  return (a: T[]) => {
    let last: R | undefined;
    a.forEach((x) => {
      const mapped = mapper(x);
      if (last === undefined || last < mapped) {
        last = mapped;
      }
    });
    return last;
  };
}

test1([1, 2, 3], max((x) => x * 2)); // Compiling Error. x is resolved to unknown
test2([1, 2, 3], max((x) => x * 2)); //Work as intended

Playground Link
Any of this is a production problem, though. I'm actually studying and playing around with typing and trying to provide the most intelligent inferences I can. I tried to add a feature to this package where some arguments could be a keyof something or a function mapper. This is where I fell in this limitation.

Run into a similar issue when trying to use typescript with @babel/types and @babel/traverse.
import  { NodePath } from "@babel/traverse";
import { ExportDefaultDeclaration, ExportNamedDeclaration } from "@babel/types";

function resolveExportDeclaration(
  path: NodePath<ExportNamedDeclaration | ExportDefaultDeclaration>,
): void {
  if (path.isExportDefaultDeclaration()) {
    const x = path;
   // path should be `NodePath<ExportDefaultDeclaration>` but is `NodePath<ExportNamedDeclaration | ExportDefaultDeclaration> & NodePath<ExportDefaultDeclaration>`
  }
}

It took me a while to figure out but it ultimately boiled down to this example:
interface BaseNode {
  type: BabelNode['type'];
}
type BabelNode = ExportDefaultDeclaration | ExportNamedDeclaration;
interface ExportDefaultDeclaration extends BaseNode {
  type: 'ExportDefaultDeclaration';
}
interface ExportNamedDeclaration extends BaseNode {
  type: 'ExportNamedDeclaration';
}

interface NodePath<T = BabelNode> {
  type: T extends null | undefined
    ? undefined
    : T extends BabelNode // <- culprit
    ? T['type']
    : string | undefined;
  isExportDefaultDeclaration(): this is NodePath<ExportDefaultDeclaration>;
}

function resolveExportDeclaration(
  path: NodePath<ExportNamedDeclaration | ExportDefaultDeclaration>,
): void {
  if (path.isExportDefaultDeclaration()) {
    const x = path;
   // path should be `NodePath<ExportDefaultDeclaration>` but is `NodePath<ExportNamedDeclaration | ExportDefaultDeclaration> & NodePath<ExportDefaultDeclaration>`
  }
}

https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgEJwM4QHIHsAmKA3gFDLJgCeADhAFxpwBGEANnoQNoDkVt3AXQDcJAL4k+KdC3YEUAXmQBRAB7VcUMABEI8AK6ttEBKzhQ4YYLhDIAPsrUaw2OAFsI+HSbMWrIEaCQsIgoquqaOvqGXqbmltbIECqQIPgYjFgcxGQUNPTI3GFOkXAGRt5xftwi4oHQ8EgO4c5uHjE+8TZJKWkZOHLIpOSSDIWOmi7unsaxvtbVYiQkdcGNWQAKFgAWADwAKsiK0mxZAHyDOSPIB90QqekgBqx2yHqpuqAeOeQA-K-vME++G+yAYN2Sd16x1khBBfz2PEkghBDAwYCgoAA5i83oRASAPCIcsAMEUIrpStEZh0-AAKACUDDAWxJyFZG22OzJRii5VmnVONSWMDeCE6yCgEAwuFYADcINz2pVrLSctRtgwOcyueMWlMlXMbPZFRSygaBQAaEiM5Cy3DAfAXcjAGDIWnq5kAOhJJt55rp9PpTvIyAQ1jRyBUh2QHq2InI4nEQA
Please fix this.

Hello. It looks like I faced the same annoying issue

/** All possible action types */
type ActionTypes = 'feature1' | 'feature2' | 'test1' | 'test2';

type Match<T extends ActionTypes, S extends ActionTypes, V> = S extends T ? V : never;

type Feature = {
    name: string;
    action: () => void;
}

type Test = {
    name: string;
    test: () => void;
}

/** Each action has its wrapper type, one wrapper can be matched to multiple actions */
type Action<T extends ActionTypes> =
    | Match<T, 'feature1', Feature>
    | Match<T, 'feature2', Feature>
    | Match<T, 'test1', Test>
    | Match<T, 'test2', Test>;

type FeatureTypes = Extract<ActionTypes, 'feature1' | 'feature2'>;

/** Type Action<T> is expected to be narrowed to Feature but it is not */
function doFeatureAction1<T extends FeatureTypes>(action: Action<T>){
    action.action(); // <=== Error: Property 'action' does not exist on type 'Action<T>'.
}

// this one works
function doFeatureAction2(action: Action<FeatureTypes>){
    action.action();
}

Playground
Maybe someone knows any workaround?

This issue is now fixed in #43183.

Wow, this was one of the most annoying issues for me, thanks.

Hooray!
But ugh I think I've been referencing this issue for years now without realizing that this issue is specifically about narrowing values whose types are generic, and not about the type parameters themselves.   I'm gonna cry I think 😃

I realize this issue is closed, but I'm still getting this behavior. I'll try and post a minimal working example but the full usage can be seen here.
TS playground link here
I have this type, PrimitiveOrConstructor:
interface typeMap { // for mapping from strings to types
  string: string;
  number: number;
  boolean: boolean;
}

type Constructor = { new(...args: any[]): any };

type PrimitiveOrConstructor =
  | Constructor
  | keyof typeMap;

and I'm using it as the generic constraint in this function, and I have to assign the variable with type T extends PrimitiveOrConstructor in order to get narrowing:
function typeGuard<T extends PrimitiveOrConstructor>(o: unknown, className: T): boolean {

  const localPrimitiveOrConstructor: PrimitiveOrConstructor = className;

  if (typeof localPrimitiveOrConstructor === 'string') {
    return typeof o === localPrimitiveOrConstructor;
  }

  return o instanceof localPrimitiveOrConstructor;
}

If I try to skip using the type variable it doesn't work, even if I define an explicit type guard function:
function typeGuard<T extends PrimitiveOrConstructor>(o: unknown, className: T): o is GuardedType<T> {

  if (isPrimitiveName(className)) {
    return typeof o === className; // className inferred as T & keyof typeMap
  }

  return o instanceof className; // error here
}

function isPrimitiveName(className: PrimitiveOrConstructor): className is keyof typeMap {
    return (typeof className === 'string')
}

Another simple example of a problem. With generic extending a union type, automatic type guards don't work.
See code in the playground.
function fn1<T extends "a" | "b" | "c">(t: T) {
  if (t === "a") {
    if (t === "b") {
      // Unreachable, error not highlited
    }
  }
}

function fn2(t: "a" | "b" | "c") {
  if (t === "a") {
    if (t === "b") {
      // Unreachable, error highlited
    }
  }
}

Another simple example of a problem. With generic extending a union type, automatic type guards don't work. See code in the playground.
function fn1<T extends "a" | "b" | "c">(t: T) {
  if (t === "a") {
    if (t === "b") {
      // Unreachable, error not highlited
    }
  }
}

function fn2(t: "a" | "b" | "c") {
  if (t === "a") {
    if (t === "b") {
      // Unreachable, error highlited
    }
  }
}

Another example. Code
function add(a: string | number, b: number) {
  if (typeof a === "string") {
    return `${a}${b}`
  }
  return a + b // ✔
}

function add2<T extends string | number>(a: T, b: number) {
  if (typeof a === "string") {
    return `${a}${b}`
  }
  return a + b // ⚠ Operator '+' cannot be applied to types 'T' and 'number'
}

Same issue here but user defined type: Code

// Type definitions

enum CarType {
    sedan = 'sedan',
    suv = 'suv',
    truck = 'truck'
}

type CarSedan = {
    type: CarType.sedan;
    randomKey1?: string;
}

type CarSUV = {
    type: CarType.suv;
    randomKey2?: number;
}

type CarTruck = {
    type: CarType.truck;
    randomKey3?: string;
}

//. Type guard using the key "type" to differentiate the union types

const isCarTruck = <
    Truck extends CarTruck,
    Others extends CarSedan | CarSUV,
    All extends Truck | Others
>(
    car: All
): car is Exclude<All, Others> =>
    (car as CarTruck)?.type === CarType.truck;

// Subset
type Union = CarTruck | CarSedan | CarSUV

// Example 1: In a normal usage its working

const func1 = (car: Union) => {
    isCarTruck(car)
        ?
        car // CarTruck
        :
        car // CarSedan | CarSUV
}

// Example 2: With generic extends it doesnt work

const func = <T extends Union>(car: T) => {
    isCarTruck(car)
        ?
        car // "Exclude<T, CarSedan | CarSUV>"" ----> CarTruck
        :
        car; // "T extends Union" ----> ?????
}

Can confirm generic union type guards still aren't working
Playground link

type Types = "1" | "2" | "3"

type XYZ<T extends Types> = {
  type: T;
  x: T extends "1"
    ? number
    : T extends "2"
    ? string
    : T extends "3"
    ? boolean
    : never;
};

function y<T extends Types>(x: XYZ<T>) {
  if(x.type === '1') {
    x.x + 1 // fails because it's number or string or boolean
  }
}

From the look of this thread, the issue is NOT really resolved at this point, and we cannot narrow dependent types?

A very high proportion of comments here are misunderstanding a fundamental aspect of how union-constrained generics work.
It is not safe to write code like this
function f<T extends number | string>(x: T, y: T): string {
    if (typeof x === "string") {
        return y; // <- No!
    }
    return "ok";
}

because a caller can legally write
f<number | string>("hello", 42);

Narrowing one variable of a type parameter's type does not give you sound information about another variable of the same type parameter's type.

@RyanCavanaugh  Gotcha, thanks for that explanation.
What about this example?
const Actions = {
	Action1: 'Action1',
	Action2: 'Action2',
} as const;
type Action = ValueOf<typeof Actions>;

// Some dynamic parameters
type ParamConstraints = {
	[Actions.Action1]: { name: string, age: number },
	[Actions.Action2]: { company: string }
};

function doSomething<TAction extends Action>(action: TAction, param: ParamConstraints[TAction]) {
	if(action === 'Action1') {
		param.name // Property 'name' does not exist on type '{ name: string; age: number; } | { company: string; }'.
	}

	if(action === 'Action2') {
		param.company // same error
	}

	switch(action) {
		case 'Action1':
			param.name // same error
			break;
		case 'Action2':
			param.company // same error
			break;
	}
}

This seems to enforce the contract for callers. Shouldn't this be safe for narrowing?
Or is this something entirely different?

This seems to enforce the contract for callers

No
// Sound upcast
const p = 'Action1' as 'Action1' | 'Action2';
// Correct call
doSomething(p, { company: 'test' });

To me that looks like self-sabotage by intentionally casting to something not intended? I'm not sure if I would consider that a case that needs defending against for that example, but I'm very likely wrong 😅
I guess this spawns 2 questions for you:

Is this sort of narrowing even possible/supported in TS?
If it is. is there a further constraint that I need to make this safe? Or how? (Does it have a name?)

This is the work-around I'm using. The key function in the following is the asUnion function, and its example use in discriminateExample. Explanation below.
type Types = {
  'Num': number
  'Str': string
}
type Names = keyof Types // 'Num' | 'Str'
type Inner<T extends Names> = Types[T]

interface Box<T extends Names> {
  type: T
  value: Inner<T>
}

// Example of generic operation on Box
function unbox<T extends Names>(box: Box<T>): Inner<T> {
  // `box.value` is correctly inferred with type `Inner<T>`
  return box.value
}

function asUnion<T extends Names>(box: Box<T>): T extends any ? Box<T> : never {
  return box as any
}

function discriminateExample<T extends Names>(box: Box<T>) {
  const { type, value } = asUnion(box);
  switch (type) {
    case 'Num': return value + 1; // `value` narrowed to `number`
    case 'Str': return value + ' text'; // `value` narrowed to `string`
  }
}

For my use case, I have a generic Box<T> container, where T is a type name (Num or Str in the example, to keep things simple).
I have some operations on boxes that I want to implement generically -- unbox is an example. And I have some operations on boxes where I want to discriminate on the different types of boxes and implement each case individually -- discriminateExample is an example. The issue, as raised in this thread, is that it's hard to do both kinds of operations on the same types: if Box<T> is a union then generic operations require casting, and if Box<T> is not a union then you can't discriminate on the individual possibilities.
The solution here is the asUnion function, which internally does a cast from the generic form to the union form, but at least the cast is only in one place. The return type of asUnion uses a conditional type to expand out the discriminated union based on all the possible type names T.
For example, if the argument of asUnion is Box<'Num' | 'Str'> then the return type is Box<'Num'> | Box<'Str'>, which is then compatible with TypeScript's narrowing logic.

A very high proportion of comments here are misunderstanding a fundamental aspect of how union-constrained generics work.

@RyanCavanaugh sorry but does this code suffer from the same issue?
function f<T extends number | string>(x: T, y: T extends number ? number : string): string {
    if (typeof x === "string") {
        return y;
    }
    return "ok";
}

For me the conditional generic type for y implies that it will narrow on the concrete implementation of x, which we asserted as string

The fix seems very incomplete to me. A simple re-assignment of the narrowed variable will break it:
type Type = 'a' | 'b';

let testVariable: 'a'

function testTypeNarrowing<T extends 'a' | 'b'>(t: T): 'a' | null {
  if (t === 'a') {
    // this assignment works, making you believe t has been correctly narrowed
    testVariable = t
    // t has not actually been narrowed here
    const x = t
    return x  //compilation error, but returning t itself woudl work!
  }
  return null
}

This of course causes all sorts of related problems. In light of this, shouldn't this issue be reopened for having a main source of reference on these kind of issues?

This also doesn't work with narrowing conditional types (tested with both enums and unions in TS 5.5):
function getConcreteEnumImpl<TEnum extends MyEnum>(myEnum: TEnum): SpecializedTypeOfEnum<TEnum> {
  switch (myEnum) {
    case MyEnum.bar: {
      return new BarEnumSpecialization(); <-- Typing error because TS does not narrow `TEnum` to `bar`
    }
    case MyEnum.foo: {
      return new FooEnumSpecialization();
    }
    default: throw new Error();
  }
}

Full TS playground link


Flatten-Tool: Add option to omit /0/ from columns

See https://github.com/OpenDataServices/flatten-tool/issues/313

Closing as the new flattening tool will either do this by default, or add an option.


Add log_level config

Adds support for configurable log_level.
Spec
Related issues
Closes #941

:broken_heart: Tests Failed

the below badges are clickable and redirect to their specific view in the CI or DOCS

Expand to view the summary

Build stats

Build Cause: [Pull request #946 opened]

Start Time: 2020-10-12T21:24:35.318+0000

Duration: 20 min 22 sec

Test stats :test_tube:

Test
Results

Failed
13

Passed
10661

Skipped
7051

Total
17725

Test errors
Expand to view the tests failures

Name: Initializing / Test / Python-python-3.5-1 / test_callback_reset – tests.config.tests

Age: 1
Duration: 0.005
Error Details: assert 3 == 2   -3   +2

Name: Initializing / Test / Python-python-3.6-1 / test_callback_reset – tests.config.tests

Age: 1
Duration: 0.005
Error Details: assert 3 == 2   -3   +2

Name: Initializing / Test / Python-python-3.9-rc-1 / test_callback_reset – tests.config.tests

Age: 1
Duration: 0.005
Error Details: assert 3 == 2   -3   +2

Name: Initializing / Test / Python-python-3.8-1 / test_callback_reset – tests.config.tests

Age: 1
Duration: 0.006
Error Details: assert 3 == 2   -3   +2

Name: Initializing / Test / Python-python-2.7-1 / test_callback_reset – tests.config.tests

Age: 1
Duration: 0.005
Error Details: assert 3 == 2   -3   +2

Name: Initializing / Test / Python-python-3.7-1 / test_callback_reset – tests.config.tests

Age: 1
Duration: 0.005
Error Details: assert 3 == 2   -3   +2

Name: Initializing / Test / windows-3.6-none / test_callback_reset – tests.config.tests

Age: 1
Duration: 0.006
Error Details: assert 3 == 2

Name: Initializing / Test / windows-2.7-none / test_callback_reset – tests.config.tests

Age: 1
Duration: 0.008
Error Details: assert 3 == 2

Name: Initializing / Test / windows-3.5-none / test_callback_reset – tests.config.tests

Age: 1
Duration: 0.007
Error Details: assert 3 == 2

Name: Initializing / Test / windows-3.7-none / test_callback_reset – tests.config.tests

Age: 1
Duration: 0.006
Error Details: assert 3 == 2

Name: Initializing / Test / Python-pypy-2-1 / test_callback_reset – tests.config.tests

Age: 1
Duration: 0.129
Error Details: assert 3 == 2   -3   +2

Name: Initializing / Test / windows-3.8-none / test_callback_reset – tests.config.tests

Age: 1
Duration: 0.019
Error Details: assert 3 == 2

Name: Initializing / Test / Python-pypy-3-1 / test_callback_reset – tests.config.tests

Age: 1
Duration: 0.059
Error Details: assert 3 == 2   -3   +2

Steps errors
Expand to view the steps failures

Name: Shell Script

Description: ./tests/scripts/docker/run_tests.sh python-2.7 none

Duration: 2 min 19 sec

Start Time: 2020-10-12T21:29:38.066+0000

log

Name: Shell Script

Description: ./tests/scripts/docker/run_tests.sh python-2.7 none

Duration: 1 min 53 sec

Start Time: 2020-10-12T21:32:06.876+0000

log

Name: Error signal

Description: Python-python-2.7-none tests failed : hudson.AbortException: script returned exit code 2

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:33:23.173+0000

log

Name: Shell Script

Description: ./tests/scripts/docker/run_tests.sh python-3.5 none

Duration: 2 min 37 sec

Start Time: 2020-10-12T21:29:47.657+0000

log

Name: Shell Script

Description: ./tests/scripts/docker/run_tests.sh python-3.5 none

Duration: 1 min 54 sec

Start Time: 2020-10-12T21:31:41.922+0000

log

Name: Error signal

Description: Python-python-3.5-none tests failed : hudson.AbortException: script returned exit code 2

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:32:53.483+0000

log

Name: Shell Script

Description: ./tests/scripts/docker/run_tests.sh python-3.6 none

Duration: 2 min 40 sec

Start Time: 2020-10-12T21:29:47.905+0000

log

Name: Shell Script

Description: ./tests/scripts/docker/run_tests.sh python-3.6 none

Duration: 1 min 54 sec

Start Time: 2020-10-12T21:31:42.641+0000

log

Name: Error signal

Description: Python-python-3.6-none tests failed : hudson.AbortException: script returned exit code 2

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:32:54.176+0000

log

Name: Shell Script

Description: ./tests/scripts/docker/run_tests.sh python-3.7 none

Duration: 3 min 49 sec

Start Time: 2020-10-12T21:29:51.515+0000

log

Name: Shell Script

Description: ./tests/scripts/docker/run_tests.sh python-3.7 none

Duration: 1 min 53 sec

Start Time: 2020-10-12T21:32:51.263+0000

log

Name: Error signal

Description: Python-python-3.7-none tests failed : hudson.AbortException: script returned exit code 2

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:34:01.372+0000

log

Name: Shell Script

Description: ./tests/scripts/docker/run_tests.sh python-3.8 none

Duration: 2 min 44 sec

Start Time: 2020-10-12T21:29:58.374+0000

log

Name: Shell Script

Description: ./tests/scripts/docker/run_tests.sh python-3.8 none

Duration: 1 min 56 sec

Start Time: 2020-10-12T21:31:57.176+0000

log

Name: Error signal

Description: Python-python-3.8-none tests failed : hudson.AbortException: script returned exit code 2

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:33:13.494+0000

log

Name: Shell Script

Description: ./tests/scripts/docker/run_tests.sh python-3.9-rc none

Duration: 2 min 37 sec

Start Time: 2020-10-12T21:30:05.482+0000

log

Name: Shell Script

Description: ./tests/scripts/docker/run_tests.sh python-3.9-rc none

Duration: 1 min 53 sec

Start Time: 2020-10-12T21:31:57.231+0000

log

Name: Error signal

Description: Python-python-3.9-rc-none tests failed : hudson.AbortException: script returned exit code 2

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:33:08.179+0000

log

Name: Shell Script

Description: ./tests/scripts/docker/run_tests.sh pypy-2 none

Duration: 3 min 11 sec

Start Time: 2020-10-12T21:30:37.845+0000

log

Name: Shell Script

Description: ./tests/scripts/docker/run_tests.sh pypy-2 none

Duration: 2 min 21 sec

Start Time: 2020-10-12T21:33:59.347+0000

log

Name: Error signal

Description: Python-pypy-2-none tests failed : hudson.AbortException: script returned exit code 2

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:36:32.599+0000

log

Name: Shell Script

Description: ./tests/scripts/docker/run_tests.sh pypy-3 none

Duration: 4 min 40 sec

Start Time: 2020-10-12T21:31:04.962+0000

log

Name: Shell Script

Description: ./tests/scripts/docker/run_tests.sh pypy-3 none

Duration: 3 min 34 sec

Start Time: 2020-10-12T21:34:54.547+0000

log

Name: Error signal

Description: Python-pypy-3-none tests failed : hudson.AbortException: script returned exit code 2

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:37:39.083+0000

log

Name: Restore files previously stashed

Description: coverage-python-2.7-twisted-18

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:43:41.293+0000

log

Name: Restore files previously stashed

Description: coverage-python-2.7-pymongo-newest

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:43:41.883+0000

log

Name: Restore files previously stashed

Description: coverage-python-2.7-memcached-newest

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:43:42.460+0000

log

Name: Restore files previously stashed

Description: coverage-python-2.7-cassandra-newest

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:43:43.063+0000

log

Name: Restore files previously stashed

Description: coverage-python-2.7-pymysql-newest

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:43:43.661+0000

log

Name: Restore files previously stashed

Description: coverage-python-3.5-flask-1.1

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:43:45.347+0000

log

Name: Restore files previously stashed

Description: coverage-python-3.5-celery-4-flask-1.0

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:43:45.943+0000

log

Name: Restore files previously stashed

Description: coverage-python-3.5-redis-newest

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:43:46.519+0000

log

Name: Restore files previously stashed

Description: coverage-python-3.5-pylibmc-newest

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:43:47.103+0000

log

Name: Restore files previously stashed

Description: coverage-python-3.5-psutil-newest

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:43:47.748+0000

log

Name: Restore files previously stashed

Description: coverage-python-3.5-pymemcache-newest

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:43:48.345+0000

log

Name: Restore files previously stashed

Description: coverage-python-3.6-flask-0.12

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:43:49.730+0000

log

Name: Restore files previously stashed

Description: coverage-python-3.6-celery-3-django-2.0

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:43:50.337+0000

log

Name: Restore files previously stashed

Description: coverage-python-3.6-pymongo-newest

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:43:50.926+0000

log

Name: Restore files previously stashed

Description: coverage-python-3.6-pylibmc-newest

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:43:51.515+0000

log

Name: Restore files previously stashed

Description: coverage-python-3.6-psutil-newest

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:43:52.124+0000

log

Name: Restore files previously stashed

Description: coverage-python-3.6-pymemcache-newest

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:43:52.782+0000

log

Name: Restore files previously stashed

Description: coverage-python-3.7-flask-1.1

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:43:54.204+0000

log

Name: Restore files previously stashed

Description: coverage-python-3.7-requests-newest

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:43:54.792+0000

log

Name: Restore files previously stashed

Description: coverage-python-3.7-pyodbc-newest

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:43:55.377+0000

log

Name: Restore files previously stashed

Description: No such saved stash ‘coverage-python-3.7-elasticsearch-7’

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:43:55.979+0000

log

Name: Restore files previously stashed

Description: coverage-python-3.7-pymysql-newest

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:43:56.872+0000

log

Name: Restore files previously stashed

Description: coverage-python-3.7-tornado-newest

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:43:57.551+0000

log

Name: Restore files previously stashed

Description: coverage-python-3.8-flask-0.12

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:43:59.668+0000

log

Name: Restore files previously stashed

Description: coverage-python-3.8-celery-3-django-2.0

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:44:00.303+0000

log

Name: Restore files previously stashed

Description: coverage-python-3.8-psycopg2-newest

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:44:00.912+0000

log

Name: Restore files previously stashed

Description: No such saved stash ‘coverage-python-3.8-elasticsearch-6’

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:44:01.522+0000

log

Name: Restore files previously stashed

Description: coverage-python-3.8-mysql_connector-newest

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:44:02.135+0000

log

Name: Restore files previously stashed

Description: coverage-python-3.8-asyncpg-newest

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:44:02.735+0000

log

Name: Restore files previously stashed

Description: coverage-python-3.8-httpx-newest

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:44:03.336+0000

log

Name: Restore files previously stashed

Description: coverage-python-3.9-rc-flask-0.12

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:44:04.602+0000

log

Name: Restore files previously stashed

Description: coverage-python-3.9-rc-celery-3-django-2.0

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:44:05.217+0000

log

Name: Restore files previously stashed

Description: coverage-python-3.9-rc-pyodbc-newest

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:44:05.823+0000

log

Name: Restore files previously stashed

Description: No such saved stash ‘coverage-python-3.9-rc-elasticsearch-7’

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:44:06.435+0000

log

Name: Restore files previously stashed

Description: coverage-python-3.9-rc-pymysql-newest

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:44:07.017+0000

log

Name: Restore files previously stashed

Description: coverage-python-3.9-rc-tornado-newest

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:44:07.624+0000

log

Name: Restore files previously stashed

Description: coverage-pypy-2-twisted-18

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:44:09.133+0000

log

Name: Restore files previously stashed

Description: coverage-pypy-2-pymongo-newest

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:44:09.707+0000

log

Name: Restore files previously stashed

Description: No such saved stash ‘coverage-pypy-2-elasticsearch-2’

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:44:10.277+0000

log

Name: Restore files previously stashed

Description: coverage-pypy-2-mysql_connector-newest

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:44:10.867+0000

log

Name: Restore files previously stashed

Description: coverage-pypy-3-flask-0.12

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:44:12.632+0000

log

Name: Restore files previously stashed

Description: coverage-pypy-3-celery-3-django-2.0

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:44:13.236+0000

log

Name: Restore files previously stashed

Description: coverage-pypy-3-pymongo-newest

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:44:13.832+0000

log

Name: Restore files previously stashed

Description: No such saved stash ‘coverage-pypy-3-elasticsearch-2’

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:44:14.418+0000

log

Name: Restore files previously stashed

Description: coverage-pypy-3-gevent-newest

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:44:15.020+0000

log

Name: Restore files previously stashed

Description: coverage-pypy-3-graphene-2

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:44:15.610+0000

log

Name: Archive the artifacts

Description: [2020-10-12T21:44:54.938Z] Archiving artifacts
Python-python-3.5-none tests failed : hudson.AbortEx

Duration: 0 min 0 sec

Start Time: 2020-10-12T21:44:54.925+0000

log

Log output
Expand to view the last 100 lines of log output

[2020-10-12T21:44:07.055Z] ERROR: No such saved stash ‘coverage-python-3.9-rc-pymysql-newest’
[2020-10-12T21:44:07.662Z] ERROR: No such saved stash ‘coverage-python-3.9-rc-tornado-newest’
[2020-10-12T21:44:09.170Z] ERROR: No such saved stash ‘coverage-pypy-2-twisted-18’
[2020-10-12T21:44:09.746Z] ERROR: No such saved stash ‘coverage-pypy-2-pymongo-newest’
[2020-10-12T21:44:10.317Z] ERROR: No such saved stash ‘coverage-pypy-2-elasticsearch-2’
[2020-10-12T21:44:10.903Z] ERROR: No such saved stash ‘coverage-pypy-2-mysql_connector-newest’
[2020-10-12T21:44:12.676Z] ERROR: No such saved stash ‘coverage-pypy-3-flask-0.12’
[2020-10-12T21:44:13.274Z] ERROR: No such saved stash ‘coverage-pypy-3-celery-3-django-2.0’
[2020-10-12T21:44:13.868Z] ERROR: No such saved stash ‘coverage-pypy-3-pymongo-newest’
[2020-10-12T21:44:14.456Z] ERROR: No such saved stash ‘coverage-pypy-3-elasticsearch-2’
[2020-10-12T21:44:15.060Z] ERROR: No such saved stash ‘coverage-pypy-3-gevent-newest’
[2020-10-12T21:44:15.649Z] ERROR: No such saved stash ‘coverage-pypy-3-graphene-2’
[2020-10-12T21:44:17.591Z] + python3 -m coverage combine
[2020-10-12T21:44:49.744Z] + python3 -m coverage xml
[2020-10-12T21:44:53.987Z] [Cobertura] Skipping Cobertura coverage report as build was not SUCCESS or better ...
[2020-10-12T21:44:53.988Z]
[2020-10-12T21:44:54.422Z] + curl -sLO https://code.jquery.com/jquery-3.3.1.slim.min.js
[2020-10-12T21:44:54.733Z] + curl -sLO<EMAIL_ADDRESS>[2020-10-12T21:44:54.938Z] Archiving artifacts
[2020-10-12T21:44:55.114Z] Stage "Building packages" skipped due to earlier failure(s)
[2020-10-12T21:44:55.215Z] Stage "Integration Tests" skipped due to earlier failure(s)
[2020-10-12T21:44:55.314Z] Stage "Benchmarks" skipped due to earlier failure(s)
[2020-10-12T21:44:55.548Z] Stage "Prepare Release" skipped due to earlier failure(s)
[2020-10-12T21:44:55.588Z] Stage "Prepare Release" skipped due to earlier failure(s)
[2020-10-12T21:44:55.691Z] Stage "Prepare Release" skipped due to earlier failure(s)
[2020-10-12T21:44:55.815Z] Stage "Prepare Release" skipped due to earlier failure(s)
[2020-10-12T21:44:56.536Z] Running on Jenkins in /var/lib/jenkins/workspace/thon_apm-agent-python-mbp_PR-946
[2020-10-12T21:44:56.826Z] [INFO] getVaultSecret: Getting secrets
[2020-10-12T21:44:57.015Z] Masking supported pattern matches of $VAULT_ADDR or $VAULT_ROLE_ID or $VAULT_SECRET_ID
[2020-10-12T21:44:57.920Z] + chmod 755 generate-build-data.sh
[2020-10-12T21:44:57.920Z] + ./generate-build-data.sh https://apm-ci.elastic.co/blue/rest/organizations/jenkins/pipelines/apm-agent-python/apm-agent-python-mbp/PR-946/ https://apm-ci.elastic.co/blue/rest/organizations/jenkins/pipelines/apm-agent-python/apm-agent-python-mbp/PR-946/runs/1 FAILURE 1222333
[2020-10-12T21:44:58.171Z] INFO: curl https://apm-ci.elastic.co/blue/rest/organizations/jenkins/pipelines/apm-agent-python/apm-agent-python-mbp/PR-946/runs/1/steps/?limit=10000 -o steps-info.json

:bug: Flaky test report
:grey_exclamation: There are not known flaky tests.
Test stats :test_tube:

Test
Results

Failed
0

Passed
11183

Skipped
8506

Total
19689

I still need to figure out why the integration tests are failing...

These tests should pass once https://github.com/elastic/apm-integration-testing/pull/962 is merged.


Style and locale flashing

Hello!
I don't know if I'm doing something wrong, but when I refresh the page, I can briefly see the button without styles and with the wrong locale.

My code is basically just:
<GoogleLogin
  onSuccess={(credentialResponse) => {
    loginWithGoogle(credentialResponse.credential);
  }}
  onError={() => {
    loginWithGoogle(null, false);
  }}
  locale={locale}
/>

Thanks in advance.

Hello @jpvg10 , Unfortunately this issue from google side, I can't do anything to solve it :(

Oh I see... 😕


Clone http.DefaultTransport rather than making our own.

This lets us inherit the useful/sane defaults of the default transport.
The most obvious benefit it inherits is supporting HTTP(S)_PROXY env variables from the http.ProxyFromEnvironment function. This lets you set http(s)/socks5 proxies for the program to use. This could be manually set on the Proxy field of Transport, but there's really no reason not to just clone the default transport as a base.
TLSHandshakeTimeout is already set to 10 seconds on the default transport so I omitted setting that, ResponseHeaderTimeout isn't set by default though so I kept that around.

Neat, I never even considered that. Though I also completely missed there being a clone() function for http.Transport.
I think I even remember trying to figure out how to use the default transport but couldn't figure it out. Forgot that casting is a thing.


DOC: I found at least 5 cases of improper spaces and font sized in readme

What's wrong with the existing documentation
The readme file looks very unprofessional and unreadable with the current improper spacing and font sizes. I have given some examples below.
Add ScreenShots

Record

[X] I agree to follow this project's Code of Conduct
[X] I'm a GSSOC'23 contributor
[X] I want to work on this issue

@1Shubham7
PLEASE ASSIGN ME THIS ISSUE


Prepare integration tests for switch of beta to main

User story
As a developer, I need to run integration tests against the stage and production instances of MDN for the beta (soon to be main) domain endpoints as well as the wiki endpoints. Currently, the integration tests assume they're testing the wiki endpoints, so there will be a large number of failures when run against the beta endpoints (after they become the main endpoints).
Acceptance criteria

[ ] The integration tests successfully run against both the wiki and beta (main) domain endpoints.

work folded into sprints #1637


Implement debouncing in search bar using rxjs

Closes #520

@byliuyang, I am getting "Unhandled Rejection (ReferenceError): chrome is not defined"

@kapillamba4 Please run yarn and try again.

Still the same

@kapillamba4 I think it because chrome only available inside Chrome.  Please install Google Chrome for testing and file a bug for @rohithbalaji123


use object instead of goblin in lucet-objdump

Over in #470, we discovered that object and faerie have different
approaches to writing relocations in shared objects.  In a nutshell,
object's approach requires applying relocations to the shared object's
data whereas faerie's does not (at least for the current structure of
lucet-objdump).
This change represents an intermediate step towards accommodating
object's relocation approach by rewriting lucet-objdump to use
object instead of goblin for reading files.  object is a little
easier to work with, a little more abstract than goblin, and various
other bits of Lucet already use object anyway.
There are no differences in lucet-objdump's output on a representative
file when lucet-objdump is compiled with and without this patch.

grr. wrong tab

(tweaked the commit just a smidge to keep a link (https://github.com/bytecodealliance/lucet/pull/470) alongside #470 in the message)

@awortman-fastly @iximeow Thank you!
@awortman-fastly Did you get a notification about review being re-requested?  I clicked the "request re-review" button on Github but it didn't seem to be changing state.

I don't think I saw anything about review re-requests, I've seen it fail to do anything once or twice now, unfortunately. I just looked back at this tab and saw a force push I didn't recall being present before.

@awortman-fastly OK, thank you for the information!


Introduce Client Hints API

This PR introduces the Client Hints API. We will always request the low entropy hints, but each high entropy hint will only be requested as set in the options.
For example,
AnalyticsBrowser.load(       ...,       { highEntropyValues: ['bitness', 'architecture', 'model', 'platformVersion', 'fullVersionList'] }     )
Would populate context.userAgentData with something like
{     "architecture": "x86",     "bitness": "64",     "brands": [         {             "brand": "Google Chrome",             "version": "113"         },         {             "brand": "Chromium",             "version": "113"         },         {             "brand": "Not-A.Brand",             "version": "24"         }     ],     "fullVersionList": [         {             "brand": "Google Chrome",             "version": "113.0.5672.92"         },         {             "brand": "Chromium",             "version": "113.0.5672.92"         },         {             "brand": "Not-A.Brand",             "version": "<IP_ADDRESS>"         }     ],     "mobile": false,     "model": "",     "platform": "macOS",     "platformVersion": "13.1.0" }
[] I've included a changeset (psst. run yarn changeset. Read about changesets here).

FYI we should document this new userAgentData object like we do our other reserved properties


TraceContext missing on TracingProducer's callback when not sampling

Describe the Bug
The TracingProducer returned from KafkaTracing wraps the underlying Producer's send(ProducerRecord, Callback) method. When this method is invoked with a span in context that has sampling enabled, a new child span is appropriately created and scoped when the Callback is asynchronously invoked by the underlying Producer. However, if the span in context does not have the sampling flag set, there is no TraceContext when the callback is invoked. This makes it impossible to do log correlation or extra field propagation for unsampled spans.
For background - TracingCallback.create(Callback, Span, CurrentTraceContext) returns the delegate back if Span.isNoop() is true. However, it does not appear to be the overall design of Brave to not continue a TraceContext for NoopSpan - the other common instrumentation doesn't do this. Indeed, the javadoc on Span.isNoop() indicates that no recording or reporting is done, but that the span should still be injected downstream - the code in TracingCallback makes that impossible, as the span is never put into scope or otherwise made available to consuming code.
I discussed this with @devinsba on gitter, who suggested I file this bug. There was some discussion there about the nature of a NoopSpan - upon investigation, a NoopSpan is created by Tracer.nextSpan() whenever FLAG_SAMPLED is not set (by way of Tracer._toSpan(TraceContext)
There is an existing test that confirms this behavior - I believe the test is wrong and the callback should be invoked with a span in scope regardless of sampling: https://github.com/openzipkin/brave/blob/master/instrumentation/kafka-clients/src/test/java/brave/kafka/clients/TracingCallbackTest.java#L28
Steps to Reproduce

Use KafkaTracing.producer(Producer) to instrument a Kafka Producer
Set a span in scope that has sampling disabled
Call Producer.send(ProducerRecord, Callback) on the instrumented producer
Observe that, when Callback is invoked asynchronously on a clean thread, CurrentTraceContext.get() is not set.

Expected Behaviour
When the callback is invoked, CurrentTraceContext.get() should contain a TraceContext with the same tracing information, extras, etc as existed when Producer.send() was invoked.

This is a bug. we should wrap all callbacks otherwise there's no way to do log correlation.


OpenBLAS: Detecting CPU failed.(Intel Kabylake 7700HQ CPU)

Hi everybody,
During the installation of the installation of Openblas with Spack I get this error
==> Error: ProcessError: Command exited with status 2:
    'make' 'CC=/home/reza/spack/lib/spack/env/gcc/gcc' 'FC=/home/reza/spack/lib/spack/env/gcc/gfortran' 'MAKE_NO_J=1' 'libs' 'netlib' 'shared'
/home/reza/spack/lib/spack/spack/build_systems/makefile.py:94, in build:
     89       def build(self, spec, prefix):
     90           """Calls make, passing :py:attr:`~.MakefilePackage.build_targets`
     91           as targets.
     92           """
     93           with working_dir(self.build_directory):
  >> 94               inspect.getmodule(self).make(*self.build_targets)

See build log for details:
  /tmp/reza/spack-stage/spack-stage-H6xYgt/OpenBLAS-0.2.19/spack-build.out

whereas the log says
==> Using default implementation: skipping edit phase.
==> 'make' 'CC=/home/reza/spack/lib/spack/env/gcc/gcc' 'FC=/home/reza/spack/lib/spack/env/gcc/gfortran' 'MAKE_NO_J=1' 'libs' 'netlib' 'shared'
getarch_2nd.c: In function ‘main’:
getarch_2nd.c:12:35: error: ‘SGEMM_DEFAULT_UNROLL_M’ undeclared (first use in this function)
     printf("SGEMM_UNROLL_M=%d\n", SGEMM_DEFAULT_UNROLL_M);
                                   ^
getarch_2nd.c:12:35: note: each undeclared identifier is reported only once for each function it appears in
getarch_2nd.c:13:35: error: ‘SGEMM_DEFAULT_UNROLL_N’ undeclared (first use in this function)
     printf("SGEMM_UNROLL_N=%d\n", SGEMM_DEFAULT_UNROLL_N);
                                   ^
getarch_2nd.c:14:35: error: ‘DGEMM_DEFAULT_UNROLL_M’ undeclared (first use in this function)
     printf("DGEMM_UNROLL_M=%d\n", DGEMM_DEFAULT_UNROLL_M);
                                   ^
getarch_2nd.c:15:35: error: ‘DGEMM_DEFAULT_UNROLL_N’ undeclared (first use in this function)
     printf("DGEMM_UNROLL_N=%d\n", DGEMM_DEFAULT_UNROLL_N);
                                   ^
getarch_2nd.c:19:35: error: ‘CGEMM_DEFAULT_UNROLL_M’ undeclared (first use in this function)
     printf("CGEMM_UNROLL_M=%d\n", CGEMM_DEFAULT_UNROLL_M);
                                   ^
getarch_2nd.c:20:35: error: ‘CGEMM_DEFAULT_UNROLL_N’ undeclared (first use in this function)
     printf("CGEMM_UNROLL_N=%d\n", CGEMM_DEFAULT_UNROLL_N);
                                   ^
getarch_2nd.c:21:35: error: ‘ZGEMM_DEFAULT_UNROLL_M’ undeclared (first use in this function)
     printf("ZGEMM_UNROLL_M=%d\n", ZGEMM_DEFAULT_UNROLL_M);
                                   ^
getarch_2nd.c:22:35: error: ‘ZGEMM_DEFAULT_UNROLL_N’ undeclared (first use in this function)
     printf("ZGEMM_UNROLL_N=%d\n", ZGEMM_DEFAULT_UNROLL_N);
                                   ^
getarch_2nd.c:69:50: error: ‘SGEMM_DEFAULT_Q’ undeclared (first use in this function)
     printf("#define SLOCAL_BUFFER_SIZE\t%ld\n", (SGEMM_DEFAULT_Q * SGEMM_DEFAULT_UNROLL_N * 4 * 1 *  sizeof(float)));
                                                  ^
getarch_2nd.c:70:50: error: ‘DGEMM_DEFAULT_Q’ undeclared (first use in this function)
     printf("#define DLOCAL_BUFFER_SIZE\t%ld\n", (DGEMM_DEFAULT_Q * DGEMM_DEFAULT_UNROLL_N * 2 * 1 *  sizeof(double)));
                                                  ^
getarch_2nd.c:71:50: error: ‘CGEMM_DEFAULT_Q’ undeclared (first use in this function)
     printf("#define CLOCAL_BUFFER_SIZE\t%ld\n", (CGEMM_DEFAULT_Q * CGEMM_DEFAULT_UNROLL_N * 4 * 2 *  sizeof(float)));
                                                  ^
getarch_2nd.c:72:50: error: ‘ZGEMM_DEFAULT_Q’ undeclared (first use in this function)
     printf("#define ZLOCAL_BUFFER_SIZE\t%ld\n", (ZGEMM_DEFAULT_Q * ZGEMM_DEFAULT_UNROLL_N * 2 * 2 *  sizeof(double)));
                                                  ^
make: *** [getarch_2nd] Error 1
Makefile:123: *** OpenBLAS: Detecting CPU failed. Please set TARGET explicitly, e.g. make TARGET=your_cpu_target. Please read README for the detail..  Stop.

KabyLake CPU identification only went in after the 0.2.19 release (for the desktop versions actually as late as last weekend), so for the moment you would need to either checkout the github "develop" branch which has the necessary patches, or build with "make TARGET=HASWELL".

Thanks Martin, it fixed the problem ;)


[WIP] feat: Augment @css-blocks/ember-cli to be a fully-fledged ember addon.

Major Work in Progress!

Depend on small changes to glimmer-analyzer and @glimmer/resolution-map-builder

Currently:

Works in Ember apps using Module Unification.
Dummy app works with CSS Blocks.
Modify glimmer analyzer to use more concepts from Glimmer's template tree analysis package.
Broccoli plugin cleans up blocks files correctly now.
Glimmer playground demo uses updated ember-cli addon.

Still To Do:

Integration tests for Ember dummy app.
Integration tests in "playground" Glimmer app.
Interfaces around Analyzer, Analysis and template -> analysis lookup can be improved.
Provide support for referencing module identifiers in @block-references. This will require re-integration with the custom loader already in-repo.
Improve options validation at all layers.

Open questions:

We need to discuss the story around module maps, how they are constructed, how and when addons may augment them, and what access build tooling has to it. Currently module maps are hard-coded. Ideally we're using a sanctioned API for this.
In a similar vein, it is likely possible to improve discovery of application routes. How can we do this better?
How do we best support engines?
Do we deliver a standalone css-blocks.css css file and inject a new <link> tag in the base page, or do we automatically concat our styles with app.css or some other file?
A number of the code splits around Glimmer/Ember can probably be resolved with small changes to the vanilla Glimmer build pipeline that we can contribute back. Should we bother / is this wanted?

Glad to see this progress! I happened to also start trying to do this exact same thing this week. A few observations from comparing notes:

the current broccoli transform can be much simpler if it just extends an existing one like broccoli-funnel. This is also likely to make it much faster because there's a bunch of rebuild optimization stuff you would get for free.

I can understand why you would tie this to module unification, but I think that's really a separable concern and we can support classic apps just fine.

related to your question about module maps: I think that's quite separate from making css-blocks work. It's great that css-blocks can do static dependency optimization, but every existing pre-MU ember app could still get huge benefit out of css-blocks even if we treated every template as an "entrypoint" and did no module dependency crawling at all. This has led me to believe that EmberAnalyzer and GlimmerAnalyzer are probably worth doing as separate implementations.

that also solves the problem of how to handle route templates.

I don't think we should have a separate <link>, I think we should make sure css-blocks runs early enough that an existing app.css can just @import "css-blocks". That lets us interoperate with multiple different preexisting style preprocessors that people may have, which enables incremental refactorings to css-blocks.

Tomorrow I will see about getting this branch running and look for opportunities to PR some of these things.

@ef4 awesome – great feedback! Would love to see your take on this, feel free to iterate on this branch. Let me know if it gives you any trouble when spinning it up.
I will happily defer to you, @tomdale and @stefanpenner on most Ember related architecture decisions since you have far more context into that universe that Chris or I – as long as we preserve the static analysis guarantees that CSS Blocks requires 🙂
Re: module unification, I agree it would be spectacular to maintain support for classic apps, and your approach of treating each template as an entrypoint is a great way to do that. I didn't get that together because with the current implementation (module unification only) I was able to leverage much of the work already done for Glimmer.
I'd love to see apps that support module unification use the GlimmerAnalyzer and have access to all the template composition data, and if module unification is not enabled it fall back to the EmberAnalyzer – a form of CSS Blocks "graceful degradation" – is that what you were thinking?

I'd love to see apps that support module unification use the GlimmerAnalyzer and have access to all the template composition data, and if module unification is not enabled it fall back to the EmberAnalyzer – a form of CSS Blocks "graceful degradation" – is that what you were thinking?

Yes, exactly. Maybe we should even name them GlimmerAnalyzer and EmberClassicAnalyzer to make it clear that even new-style Ember apps use the GlimmerAnalyzer.

I should clarify: switching to module unification by itself is not sufficient to get a complete static dependency map of an Ember app.  There are too many other dynamic escape valves, ranging from the {{component ...}} helper (which is a legit thing we want to keep, perhaps just with some additional scoping hints to make it clear which set of components are eligible to go inside of it) to things like people passing arbitrary templates to Route#render (which I would be happy to kill).

I was trying to test this branch against an actual module unification ember app and immediately ran into gaps between how MU works and how GlimmerJS works. For example, GlimmerJS doesn't understanding routes, so a hello-world ember app with just src/ui/routes/application/template.hbs blows up.
I'm going to make things work first without trying to reuse the GlimmerJS analyzer against Ember (regardless of whether using MU or not). The work to unify is not specific to css-blocks.

Hm, the addon in this branch should discover route templates / stylesheets and automatically use them as entry points – hopefully that is what your edit is referencing! If it still isn't discovering them, I'd call that a bug.
Re: MU static escape valves – I remember way back when we were building out our Glimmer experiment a while back, files using the {{component}} helper were required to add an import comment at the top of the file with all possible dynamic components used so Glimmer could properly discover them and build out the static template dependency tree:
{{!-- import ComponentName1 ComponentName2--}}
{{component dynamicName}}

Is this still a pattern in Glimmer, and/or one that will be used in MU Ember apps?

Hm, the addon in this branch should discover route templates / stylesheets and automatically use them as entry points – hopefully that is what your edit is referencing!

Yes, I did get past that one.

Is this still a pattern in Glimmer, and/or one that will be used in MU Ember apps?

It's possible addition, but it's not part of MU as written, so it would be premature to assume anything about its exact implementation.
How have you been testing this branch? I'm unable to get the dummy app to actually run. I hit and solved the following

you have a fork of glimmer-analyzer and it can't run directly from github (it needs to be built first, so I'm cloning, building, and yarn linking).
I needed master of ember-cli with EMBER_CLI_MODULE_UNIFICATION=enabled
lerna bootstrap was failing to link things up properly because there is version skew between packages on this branch. I fixed that by merging master into here.

Next issue is that the analyzer is attempting to locate templates under packages/@css-blocks/ember-cli/src instead of packages/@css-blocks/ember-cli/tests/dummy/src, so the build fails. The simple fix (pointing the analyzer at ember-cli/tests/dummy instead of ember-cli) doesn't work because it also expects to find package.json. So it will need to learn about the distinction.
(But also I suspect it's incorrect to try to use glimmer-resolution-map-builder against Ember apps -- that is a glimmerJS only library. Instead the common interface is glimmer-resolver, which is tested against both glimmerJS and ember.)

How have you been testing this branch? I'm unable to get the dummy app to actually run. I hit and solved the following

I've been testing in the dummy app – your steps to fix seem correct, but make sure that you built version of glimmer-analyzer is also linked up to the forked @glimmer/resolution-map-builder I mentioned in the issue description.

Next issue is that the analyzer is attempting to locate templates under packages/@css-blocks/ember-cli/src instead of packages/@css-blocks/ember-cli/tests/dummy/src

That logic lives in @css-blocks/ember-cli/index.js:140-160. Its not particularly elegant, but the different paths are resolved there. Sounds like they're not being passed down to either  glimmer-analyzer or its child @glimmer/resolution-map-builder correctly. Maybe a problem with project linking? I know I made a change to how glimmer-analyzer propagates the src directory through.

But also I suspect it's incorrect to try to use glimmer-resolution-map-builder against Ember

Probably! I'm not privy to much of the project toolchain split – will happily defer to the subject matter experts here. Although as an integrator, since both projects use resolution maps at their core, I'd expect some kind of consolidated tool chain to be available ¯_(ツ)_/¯

I now have this branch working locally, I was missing a few more places that needed to use the fork of @glimmer/resolution-map-builder and I had missed a recompile of some of the @css-blocks packages.

Here's a PR targeting your branch, to start adding acceptance tests. Plus it contains some questions about desired semantics: https://github.com/linkedin/css-blocks/pull/178

Closing in favor of https://github.com/linkedin/css-blocks/pull/185 👍


Move the status icon

Current layout

Would be nice to see

Why the change?
There's that extra annoying space (highlighted):

The current layout is this, there's no extra space, the text is aligned right:

You didn't get it right. I'm not saying it should be centered. I mean the icon should be moved to top, because the text is already centered (at least on my side) and it doesn't look well.

The current layout is this, there's no extra space, the text is aligned left:

That's weird. On my side it's centered. I'll investigate and will let you know.


Symbol error found

I sir
If in one XSCHEM in terminal without any directory I got symbol error

then if got to directory
.xschem/xschem_library/xschem_sky130 I got no error

But I still not install open_pdk

I sir
If in one XSCHEM in terminal without any directory I got symbol errors

xschem needs to know the directory where symbols are located. Either add this directory to XSCHEM_LIBRARY_PATH or start xschem in the current directory, since current directory is added to XSCHEM_LIBRARY_PATH by the xschemrc file.
If you start xschem from a different directory you should provide a xschemrc file:
xschem --rcfile /path/to/xschemrc.
see this manual page for details on symbol lookup:
https://xschem.sourceforge.io/stefan/xschem_man/tutorial_xschem_libraries.html

Sorry sir I may not explain problem correctly
First I try to open XSCHEM in terminal i show in image


SFTP UploadFiles Renci.SshNet library needs an update

Due to https://github.com/FrendsPlatform/Frends.SFTP/security/dependabot/4 vulnerability Renci.SshNet library needs to be updated and
client.ConnectionInfo.KeyExchangeAlgorithms.Remove("curve25519-sha256");
client.ConnectionInfo.KeyExchangeAlgorithms.Remove("curve25519-sha256@libssh.org");

needs to be added after SftpClient is created.

Library updated in #20 PR.